6.10. Yayınlama (Broadcasting)¶
Bir ikili operatör, şekilleri tam olarak eşleşmeyen iki dizi aldığında, numpy hata yükseltmez – yayınlama (broadcast) yapar. Yayınlama, iki şeklin uyumlu olup olmadığına ve uyumluysa daha küçük olanın daha büyük olana uyacak şekilde sanal olarak nasıl genişletileceğine karar veren küçük bir kurallar kümesidir.
6.10.1. Kurallar¶
İki işlenen A ve B şekillerine sahip olduğunda, numpy bunları iki adımda işler.
Rankları eşleştirin. Bir işlenenin diğerinden daha az ekseni varsa,
numpyher iki şekil de aynı sayıda eksene sahip olana kadar şeklinin önünü sanal olarak boyutu 1 olan eksenlerle doldurur.(3,)şeklinde 1 boyutlu bir işlenen,(2, 3)şeklinde 2 boyutlu bir işlenenle eşleştirildiğinde,(2, 3)‘e karşı(1, 3)olur.Her ekseni kontrol edin. Artık eşit uzunlukta olan şekiller eksen eksen incelendiğinde, her boyut çifti iki koşuldan birini sağlamalıdır: boyutlar eşittir veya bunlardan biri 1’dir. Boyutu 1 olan bir eksen, işlem için diğer tarafın boyutuna sanal olarak genişletilir.
(2, 3)‘e karşı(1, 3)çifti uyumludur çünkü ilk eksende 1 vardır (2’ye genişler) ve ikinci eksen eşleşir (3 == 3); sonuç(2, 3)şeklindedir.
Herhangi bir eksen çifti hiçbir koşulu sağlamazsa, şekiller uyumsuzdur ve operatör ValueError yükseltir.
6.10.2. Örnekler¶
Herhangi bir diziye karşı bir skaler. Skaler (1,) şekli gibi davranır ve her şeye genişler:
a = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float)
a + 10 # (2, 3) + scalar -> (2, 3)
Bir 2 boyutlu matris üzerinde 1 boyutlu vektör. Kural 1, (3,)‘ü (1, 3) yapmak için boyutu 1 olan bir ekseni öne ekler; kural 2 ardından bu satırı a‘nın her sütunu boyunca aşağı genişletir:
row = np.array([100, 200, 300], dtype=np.float)
a + row # (2, 3) + (3,) -> (2, 3)
Eşit uzunlukta iki 1 boyutlu dizi, eleman bazında toplanır – yayınlamaya gerek yoktur:
np.arange(4) + np.arange(4)
Bir satır vektörüne karşı bir sütun vektörü, 2 boyutlu bir “dış” şekil üretir: rank ekleme sonrasında (4, 1) ile (3,) eşleştirildiğinde (1, 3)‘e karşı (4, 1) olur ve kural 2 her işleneni boyutu 1 olan ekseni boyunca genişletir:
x = np.array([1, 2, 3, 4]).reshape((4, 1)) # column
y = np.array([10, 20, 30]) # row
x + y # (4, 3) matrix
Aynı şekil kuralları, arctan2() dahil olmak üzere herhangi bir iki argümanlı ufunc için geçerlidir:
np.arctan2(y, 1.0)
np.arctan2(y, x)
6.10.3. Yayınlamanın ayırmadığı şey¶
Genişletme sanaldır. numpy her iki işleneni birlikte gezer; daha küçük olanı kopyalamak yerine yayınlama ekseni boyunca yeniden okur. Daha kısa dizinin verileri bellekte asla çoğaltılmaz.
Bellek için önemli olan, çıktı dizisinin boyutudur. a + row, a artı row‘un şeklinde değil, a‘nın şeklinde bir çıktı ayırır. Uzun yayınlama zincirleri yine de büyük ara değerler üretebilir.
6.10.4. Yayınlama ters gittiğinde¶
Klasik başarısızlık, ikisinden hiçbirinin genişletilecek boyutu 1 olan bir ekseninin olmadığı ve boyutların uyuşmadığı iki şekildir – örneğin (4, 3)‘e karşı (3, 4). Kural 2 bir 3’ü bir 4’e eşleştiremez, bu yüzden numpy ValueError yükseltir.
Daha ince bir sorun ise başarılı olan ancak uygulamanın amaçladığı şekilde olmayan bir yayınlamadır. (5, 1)‘e karşı (5,) kanonik durumdur: rank ekleme (5,)‘i (1, 5) yapar ve bu, (5, 1)‘e karşı yayınlanarak bir (5, 5) matrisi üretir – iki vektörün dış kombinasyonu, uygulamanın muhtemelen istediği uzunluk-5 eleman bazında sonuç değil. Tereddüt ettiğinizde, her iki tarafta da shape‘i yazdırın ve reshape() veya transpose()‘a başvurmadan önce kuralları adım adım inceleyin.