6.12. Seçim ve yeniden düzenleme

İndirgemeler bir diziyi bir skalere veya daha düşük rank’lı bir sonuca daraltır. Seçim ise hangi elemanların hayatta kalacağını ve nerede sonlanacaklarını belirleyen işlemleri kapsar: koşullu seçim, kırpma, sıralama, indeks arama, bir eksen boyunca yeniden sıralama.

6.12.1. Koşullu seçim

where(), koşulun doğru olduğu yerlerde x öğesinden, aksi takdirde y öğesinden elemanlar alan bir dizi döndürür. Üç işlenen birlikte yayınlanır:

a = np.array([1, 2, 3, 4, 5], dtype=np.float)
np.where(a < 3, a, 0.0)
# array([1.0, 2.0, 0.0, 0.0, 0.0])

Bu, Python döngüsü yazmadan “eleman başına if/else” için doğru araçtır.

clip(), maximum(lo, minimum(a, hi)) ifadesinin kısaltmasıdır – değerleri bir aralığa doyurur:

np.clip(a, 2.0, 4.0)
# array([2.0, 2.0, 3.0, 4.0, 4.0])

maximum() ve minimum(), iki işlenen alır ve eleman bazında daha büyük / daha küçük olanı döndürür:

np.maximum(a, 3.0)
np.minimum(a, np.array([5, 4, 3, 2, 1]))

6.12.2. İndeks bulma

nonzero(), sıfır olmayan her elemanın koordinatlarını, boyut başına bir indeks dizisine bölünmüş olarak döndürür. 2 boyutlu bir girdi için sonuç iki diziden oluşan bir demettir: ilki satır indekslerini, ikincisi sütun indekslerini tutar. Bunları sütun bazında eşleştirmek, her sıfır olmayan konumun (row, col) değerini verir:

m = np.array([[0, 2, 0],
              [3, 0, 0]], dtype=np.float)
np.nonzero(m)
# (array([0, 1], dtype=uint16), array([1, 0], dtype=uint16))

m içindeki sıfır olmayan girdiler m[0, 1] = 2 ve m[1, 0] = 3. Döndürülen ilk dizi [0, 1] bunların satır indekslerini verir; ikincisi [1, 0] ise sütun indekslerini verir. İki diziyi yan yana okumak (0, 1) ve (1, 0) konumlarını yeniden elde eder.

İki indirgeme de indeks üretir:

  • argmin() / argmax() – en küçük / en büyük elemanın indeksi.

  • argsort() – girdiyi belirtilen eksen boyunca (varsayılan olarak sonuncu) sıralayacak bir tamsayı dizisi:

    a = np.array([40, 10, 30, 20], dtype=np.uint8)
    idx = np.argsort(a)             # array([1, 3, 2, 0], dtype=uint16)
    a[idx]                          # array([10, 20, 30, 40])
    

    argsort her zaman uint16 döndürür; dolayısıyla sıralanan dizinin sıralanan eksende en fazla 65.535 elemanı olmalıdır.

bincount(), 1 boyutlu bir uint8 / uint16 girdisinde her negatif olmayan tamsayının kaç kez geçtiğini sayar:

histogram = np.bincount(np.array([0, 1, 1, 2, 2, 2], dtype=np.uint8))
# array([1, 2, 3], dtype=uint16)

Python döngüsü yazmadan küçük tamsayılı piksel değerlerinin histogramlarını oluşturmak için kullanışlıdır.

6.12.3. Sıralama ve yeniden sıralama

sort(), diziyi belirtilen eksen boyunca (varsayılan olarak sonuncu) sıralanmış bir kopyasını döndürür. Yerinde bir sürüm için diziye doğrudan sort() uygulayın:

np.sort(np.array([3, 1, 2], dtype=np.float))
# array([1.0, 2.0, 3.0])

flip(), belirtilen eksen boyunca sırayı tersine çevirir (hiçbir axis geçilmediğinde her eksen):

np.flip(np.array([1, 2, 3, 4]))
# array([4, 3, 2, 1])

roll(), elemanları belirtilen sayı kadar döngüsel olarak kaydırır. Halka arabelleği (ring buffer) tarzı bir kaydırma yazmacı uygulamak için kullanışlıdır:

np.roll(np.array([1, 2, 3, 4]), 1)
# array([4, 1, 2, 3])

take(), gelişmiş indekslemenin açık biçimidir – elemanları rastgele indekslerden seçer:

a = np.array([10, 20, 30, 40, 50], dtype=np.uint8)
np.take(a, [0, 2, 4])
# array([10, 30, 50], dtype=uint8)

6.12.4. Filtreleme ve yapısal düzenlemeler

compress(), boolean indekslemenin açık biçimidir – a öğesinin boolean koşula göre seçilen dilimlerini döndürür:

a = np.array([10, 20, 30, 40], dtype=np.uint8)
np.compress(a > 15, a)
# array([20, 30, 40], dtype=uint8)

delete(), belirtilen indekslerdeki girdiler kaldırılmış bir kopya döndürür:

a = np.array([10, 20, 30, 40, 50], dtype=np.uint8)
np.delete(a, [1, 3])
# array([10, 30, 50], dtype=uint8)

diff(), dizinin bir eksen boyunca n. ayrık ileri farkını döndürür. Komşu örnekler arasındaki birinci dereceden değişimleri hesaplamak için kullanılır:

samples = np.array([1, 3, 6, 10, 15], dtype=np.float)
np.diff(samples)
# array([2.0, 3.0, 4.0, 5.0])

6.12.5. Her işlemin maliyeti

Bu sayfadaki neredeyse her işlev, yeni ayrılmış bir dizi döndürür. İki istisna:

  • sort() yerinde sıralar; serbest işlev sort() ise sıralanmış bir kopya döndürür.

  • take(), halihazırda var olan bir arabelleğe yazmak için bir out= anahtar sözcüğü kabul eder.

Saniyede birçok kez çalışan bir döngüde, yerinde çalışan sort() işlevini tercih edin ve diğer her yerde önceden ayrılmış arabellekleri yeniden kullanın. Boolean maskelerin kendileri, karşılaştırma her çalıştığında ayrılır – bir maskeyi her yinelemenin içinde yeniden oluşturmak yerine bir kez oluşturun ve işlemler arasında yeniden kullanın.