Chapter sebelumnya memperlihatkan bahwa (3, 4) sanggup beroperasi dengan (4,) maupun (3, 1). NumPy tidak menebak — keputusan itu lahir dari dua aturan resmi yang didokumentasikan di numpy.org/doc/stable/user/basics.broadcasting.html. Memahmi kedua aturan tersebut membuat kita bisa memprediksi bentuk hasil sebelum kode dijalankan, dan memahami pesan error ketika bentuk memang tak cocok.

Bab ini membahas:

  • Aturan 1: cara menyelaraskan bentuk dari kanan ke kiri.
  • Aturan 2: syarat kompatibilitas per dimensi dan penentuan bentuk hasil.
  • Pesan ValueError yang muncul ketika kedua aturan dilanggar.

Aturan 1: selaraskan bentuk dari kanan #

Perbandingan dua bentuk dimulai dari dimensi terakhir (paling kanan), lalu bergerak ke kiri. Dimensi yang tidak dimiliki salah satu operand dianggap bernilai 1. Untuk (3, 4) versus (4,), penyelarasan berjalan seperti ini:

text
(3, 4)
(   4,)   ←  dimensi kiri tidak ada, dianggap bernilai 1
(1, 4)    ←  bentuk setelah dilengkapi

Vektor potongan (4,) kembali memperoleh dimensi baru bernilai 1 di depan, persis seperti perlakuan “seolah (1, 4)” pada Chapter Pengenalan Broadcasting. Langkah yang sama berlaku untuk bentuk berapa pun dimensi: (2, 3, 4) versus (4,) diselaraskan menjadi (2, 3, 4) versus (1, 1, 4).

Aturan 2: dimensi kompatibel bila sama atau bernilai 1 #

Setelah terselaras, tiap pasangan dimensi diperiksa dengan syarat: kedua nilai sama, atau salah satunya bernilai 1. Bentuk hasil pada tiap dimensi mengambil nilai yang terbesar. Dua pasangan pada contoh kita lolos:

  • (3, 4) versus (1, 4): dimensi pertama 3 lawan 1 → hasil 3; dimensi kedua 4 sama dengan 4 → hasil 4.
  • (3, 4) versus (3, 1): dimensi pertama sama-sama 3 → hasil 3; dimensi kedua 4 lawan 1 → hasil 4.

Kedua pasangan menghasilkan (3, 4), dan dimensi bernilai 1 diperluas secara virtual agar mengejar nilai terbesar.

Memeriksa bentuk dengan np.broadcast_shapes #

Fungsi np.broadcast_shapes menjalankan kedua aturan itu terhadap bentuk saja — tanpa perlu membuat array. Cocok untuk merencanakan operasi:

python
import numpy as np

print(np.broadcast_shapes((3, 4), (4,)))
print(np.broadcast_shapes((3, 4), (3, 1)))
print(np.broadcast_shapes((2, 3, 4), (4,)))
print(np.broadcast_shapes((5, 1), (1, 6)))

Output yang Dihasilkan:

text
(3, 4)
(3, 4)
(2, 3, 4)
(5, 6)
  1. Baris 3: (4,) dilengkapi menjadi (1, 4) lalu diperluas ke tiga baris → (3, 4).
  2. Baris 4: (3, 1) menyelaraskan langsung tanpa pelengkap; kolom 1 diperluas menjadi 4 → (3, 4).
  3. Baris 5: (4,) menjadi (1, 1, 4); dua dimensi depan menyesuaikan → (2, 3, 4).
  4. Baris 6: kedua operand bernilai 1 pada dimensi berbeda — 5 lawan 1 → 5, 1 lawan 6 → 6 → (5, 6). Kedua sisi boleh saling memperluas.

Tabel berikut merangkum contoh-contoh tersebut beserta alasannya:

Bentuk pertamaBentuk keduaHasilAlasan
(3, 4)(4,)(3, 4)(4,) dilengkapi menjadi (1, 4); baris 3 lawan 1 diperluas
(3, 4)(3, 1)(3, 4)kolom 4 lawan 1 diperluas
(2, 3, 4)(4,)(2, 3, 4)(4,) menjadi (1, 1, 4); dua dimensi depan diperluas
(5, 1)(1, 6)(5, 6)kedua dimensi bernilai 1 saling diperluas
(3, 4)(3,)errordimensi terakhir 4 lawan 3: tidak sama dan tak ada yang bernilai 1

Ketika aturan dilanggar #

Baris terakhir tabel adalah satu-satunya jalan menuju error. Kita coba langsung dan tangkap pesannya dengan try/except:

python
import numpy as np

try:
    hasil = np.arange(12).reshape(3, 4) + np.arange(3)
except ValueError as e:
    print("ValueError:", e)

Output yang Dihasilkan:

text
ValueError: operands could not be broadcast together with shapes (3,4) (3,)
  1. Baris 3-5 (try): np.arange(3) berbentuk (3,). Setelah dilengkapi menjadi (1, 3), dimensi terakhir membandingkan 4 lawan 3 — tidak sama dan tidak ada yang bernilai 1.
  2. Baris 6-7 (except): ValueError ditangkap dan pesannya dicetak. Pesan menyebut kedua bentuk secara eksplisit, (3,4) dan (3,) — informasi pertama yang perlu dibaca saat debugging.

Fungsi np.broadcast_shapes((3, 4), (3,)) juga memunculkan ValueError dengan pesan serupa, sehingga bentuk yang diragukan bisa diuji lebih dulu tanpa mengeksekusi operasi beratnya.