6.10. Broadcasting

Ketika operator biner mendapatkan dua array yang bentuknya tidak cocok persis, numpy tidak memunculkan kesalahan -- ia melakukan broadcasting. Broadcasting adalah sekumpulan aturan kecil yang menentukan apakah dua bentuk kompatibel dan, jika ya, bagaimana yang lebih kecil secara virtual diregangkan untuk cocok dengan yang lebih besar.

6.10.1. Aturan-aturan

Ketika dua operan memiliki bentuk A dan B, numpy memprosesnya dalam dua langkah.

  1. Cocokkan rank. Jika satu operan memiliki lebih sedikit sumbu daripada yang lain, numpy secara virtual menambahkan sumbu berukuran-1 di depan bentuknya hingga kedua bentuk memiliki jumlah sumbu yang sama. Operan 1-D dengan bentuk (3,) yang dipasangkan dengan operan 2-D dengan bentuk (2, 3) menjadi (1, 3) terhadap (2, 3).

  2. Periksa setiap sumbu. Dengan menelusuri bentuk dengan panjang yang sama sumbu demi sumbu, setiap pasangan ukuran harus memenuhi salah satu dari dua kondisi: ukurannya sama, atau salah satunya adalah 1. Sumbu berukuran-1 secara virtual diregangkan ke ukuran sisi lainnya untuk operasi. Pasangan (1, 3) terhadap (2, 3) kompatibel karena sumbu pertama memiliki nilai 1 (diregangkan menjadi 2) dan sumbu kedua cocok (3 == 3); hasilnya memiliki bentuk (2, 3).

Jika ada pasangan sumbu yang tidak memenuhi satu pun kondisi, bentuknya tidak kompatibel dan operator memunculkan ValueError.

6.10.2. Contoh

Skalar terhadap array apa pun. Skalar bertindak seperti bentuk (1,) dan diregangkan ke apa pun:

a = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float)
a + 10                 # (2, 3) + scalar -> (2, 3)

Vektor 1-D melintasi matriks 2-D. Aturan 1 menambahkan sumbu berukuran-1 untuk mengubah (3,) menjadi (1, 3); aturan 2 kemudian meregangkan baris itu ke bawah setiap kolom a

row = np.array([100, 200, 300], dtype=np.float)
a + row                # (2, 3) + (3,) -> (2, 3)

Dua array 1-D dengan panjang yang sama ditambahkan secara elemen -- tidak diperlukan broadcasting:

np.arange(4) + np.arange(4)

Vektor kolom terhadap vektor baris menghasilkan bentuk "luar" 2-D: (4, 1) dipasangkan dengan (3,) menjadi (4, 1) terhadap (1, 3) setelah penambahan rank, dan aturan 2 meregangkan setiap operan sepanjang sumbu berukuran-1 miliknya:

x = np.array([1, 2, 3, 4]).reshape((4, 1))     # column
y = np.array([10, 20, 30])                      # row
x + y                                           # (4, 3) matrix

Aturan bentuk yang sama berlaku untuk ufunc dua-argumen apa pun, termasuk arctan2()

np.arctan2(y, 1.0)
np.arctan2(y, x)

6.10.3. Apa yang tidak dialokasikan oleh broadcasting

Peregangan bersifat virtual. numpy menelusuri kedua operan bersamaan, membaca ulang yang lebih kecil sepanjang sumbu broadcast-nya alih-alih menyalinnya. Data array yang lebih pendek tidak pernah direplikasi dalam memori.

Ukuran array output yang penting untuk memori. a + row mengalokasikan output dengan bentuk a, bukan bentuk a ditambah bentuk row. Rantai broadcasting panjang tetap dapat menghasilkan intermediat yang besar.

6.10.4. Ketika broadcasting salah

Kegagalan klasik adalah dua bentuk di mana keduanya tidak memiliki sumbu berukuran-1 untuk diregangkan dan ukurannya berbeda -- (3, 4) terhadap (4, 3), misalnya. Aturan 2 tidak dapat mencocokkan 3 terhadap 4, sehingga numpy memunculkan ValueError.

Masalah yang lebih halus adalah broadcast yang berhasil, tetapi tidak seperti yang dimaksudkan aplikasi. (5,) terhadap (5, 1) adalah kasus kanonik: penambahan rank mengubah (5,) menjadi (1, 5), yang melakukan broadcast terhadap (5, 1) untuk menghasilkan matriks (5, 5) -- kombinasi luar dari dua vektor, bukan hasil elemen-wise sepanjang-5 yang mungkin diinginkan aplikasi. Jika ragu, cetak shape pada kedua sisi dan ikuti aturan sebelum menggunakan reshape() atau transpose().