6.9. Evrensel işlevler

Bir evrensel işlev (ufunc), tek bir çağrıda bir dizinin her elemanına uygulanan bir matematik işlevidir. Önceki sayfadaki aritmetik operatörler, operatör söz dizimi giymiş evrensel işlevlerdir; bu sayfa ise trigonometri, exp / log, yuvarlama ve birkaç başka işlemi kapsayan adlandırılmış olanların kataloğudur.

Her ufunc bir skaler, bir Python yinelenebiliri veya bir ndarray kabul eder ve ya tek bir float (girdi skaler olduğunda) ya da bir float ndarray döndürür:

from ulab import numpy as np

np.exp(2.0)                    # 7.389...
np.sin(range(4))               # 1-D float ndarray
np.sqrt([1, 4, 9, 16])         # array([1.0, 2.0, 3.0, 4.0])

a = np.arange(9).reshape((3, 3))
np.exp(a)                      # 3x3 float ndarray

6.9.1. Katalog

numpy, gömülü bir uygulamanın en sık başvurduğu matematik işlevlerini sunar:

Her işlev tüm diziyi tek bir kütüphane çağrısında işler. math.sin() işlevini eleman eleman çağıran bir Python liste anlamasına (list comprehension) göre hızlanma, tipik bir arabellekte 10-30 kattır.

6.9.2. out= anahtar sözcüğü

Her ufunc çağrısı normalde çıktısını tutmak için yeni bir sonuç dizisi ayırır. Saniyede birçok kez çalışan bir döngüde bu ayırmalar birikir ve RAM israf eder. out= – girdiyle aynı şekle sahip, halihazırda var olan bir float dizi – geçmek, yeni bir dizi ayırmak yerine sonucu o diziye yazar:

x = np.linspace(0, 2 * np.pi, num=256)
y = np.zeros(256)

while True:
    np.sin(x, out=y)
    # use y ...

out yanlış dtype veya şekle sahipse, işlev bir istisna yükseltir. Bu anahtar sözcük, bu sayfadaki her ufunc’ta desteklenir; akışlı bir sinyal işleme döngüsünü ayırmasız tutmanın en temiz yoludur.

6.9.3. İki argümanlı ufunc’lar

arctan2(), yukarıdaki listedeki tek gerçek iki argümanlı ufunc’tur – y / x ifadesinin çeyrek-bölge farkındalığına sahip arktanjantını döndürür ve iki işleneni yayınlar:

y = np.array([1, 2.2, 33.33, 444.444])
np.arctan2(y, 1.0)             # against a scalar
np.arctan2(1.0, y)             # the other way
np.arctan2(y, y)               # against another array

6.9.4. Evrensel işlevleri bir araya getirme

Evrensel işlevler, diğer dizi ifadeleri gibi bir araya getirilebilir. Kamerada karşılaşılan birkaç örüntü:

Gama düzeltmesi (float uzayında)

gamma = 0.5
out = 255.0 * (frame / 255.0) ** gamma

Basit bir alçak geçiren yumuşatıcı (alpha 1.0 değerine yakın olunca güncelleme yavaş olur):

alpha = 0.95
filtered = alpha * filtered + (1.0 - alpha) * sample

Sigmoid

sigmoid = 1.0 / (1.0 + np.exp(-x))

dB cinsinden güç spektrumu

spectrum = 20.0 * np.log10(np.abs(real) + 1e-12)

6.9.5. np.vectorize

Sıradan bir Python işlevi, vectorize() ile ufunc biçimine yükseltilebilir. Ortaya çıkan çağrılabilir nesne, skalerleri, yinelenebilirleri veya ndarray değerlerini kabul eder:

def f(x):
    return x * x

vf = np.vectorize(f)

vf(44.0)                          # array([1936.0])
vf(np.array([1, 2, 3, 4]))        # array([1.0, 4.0, 9.0, 16.0])
vf([2, 3, 4])                     # array([4.0, 9.0, 16.0])

Varsayılan olarak sonuç dtype’ı float olur. otypes= bunu geçersiz kılar:

vf_u8 = np.vectorize(f, otypes=np.uint8)
vf_u8([1, 2, 3, 4])
# array([1, 4, 9, 16], dtype=uint8)

Python işlevi tek bir argüman almalı ve tek bir sayı döndürmelidir.

vectorize() çoğunlukla söz dizimseldir – sarmalanan Python işlevi yine de eleman başına bir kez çalışmak zorundadır, dolayısıyla gerçek bir ufunc’ın önlediği eleman başına yorumlayıcı maliyetinin çoğu geri gelir. Gerçek bir evrensel işlevin 30 katlık hızlanması yerine, bir liste anlamasına göre mütevazı bir %30-%50 hızlanma bekleyin. Bir işlevin aynı ad altında skalerler, listeler ve diziler üzerinde çalışması gerektiğinde doğru araçtır – ham hız hedef olduğunda değil.

Yukarıda listelenen her evrensel işlevin tam çağrı imzaları için bkz. numpy — numpy uyumlu dizi işlemleri.