ValueError: operands could not be broadcast together adalah pesan error yang paling sering dijumpai pemula NumPy. Error itu hampir selalu berawal dari satu kebiasaan yang terlewat: memeriksa bentuk (shape) dua array sebelum mengoperasikannya. Membiasakan diri memeriksa bentuk jauh lebih murah daripada menebak-nebak dari pesan error saat program berjalan.

Bab ini merangkum kebiasaan tersebut: membandingkan shape sebelum operasi, memperkenalkan cara berpikir aturan broadcasting lewat np.broadcast_shapes, membaca pesan error bentuk yang tidak cocok, dan menutup dengan daftar periksa praktis.

Membandingkan Bentuk Sebelum Operasi #

Cara termudah memastikan dua array boleh dioperasikan elemen-per-elemen adalah membandingkan atribut shape keduanya.

python
import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[10, 20, 30], [40, 50, 60]])
print(a.shape == b.shape)
c = np.arange(3)
print(a.shape == c.shape)
print(a + b)

Output yang Dihasilkan:

text
True
False
[[11 22 33]
 [44 55 66]]

Baris demi baris:

  1. Baris 5 (a.shape == b.shape): kedua array berbentuk (2, 3), sehingga perbandingan mencetak True; penjumlahan element-wise dijamin aman.
  2. Baris 6-7: c berbentuk (3,), berbeda dari (2, 3), sehingga perbandingan mencetak False. Bentuk berbeda tidak otomatis berarti error — di sinilah broadcasting masuk.
  3. Baris 8 (a + b): penjumlahan berjalan tanpa hambatan karena bentuknya identik; setiap pasangan elemen dijumlahkan langsung.

Pratinjau Aturan Broadcasting #

Ketika bentuk berbeda, NumPy mengikuti aturan broadcasting: bandingkan dimensi kedua array mulai dari belakang (trailing dimension). Sepasang dimensi cocok bila nilainya sama, salah satunya bernilai satu, atau salah satu array tidak memiliki dimensi itu lagi. Fungsi np.broadcast_shapes menerapkan aturan tersebut pada sekumpulan bentuk tanpa perlu menjalankan operasi apa pun.

python
import numpy as np

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

Output yang Dihasilkan:

text
(3, 4)
(4, 3)
(2, 2)

Mari kita bedah tiap baris:

  1. Baris 3: (3, 1) dan (1, 4). Dari belakang: 1 melawan 4 → hasil 4; 3 melawan 1 → hasil 3. Bentuk broadcast-nya (3, 4).
  2. Baris 4: (4, 3) dan (3,). Array kedua lebih pendek, sehingga diperlakukan seperti (1, 3); dimensi 3 melawan 3 cocok, dimensi 1 melawan 4 dikembangkan. Hasilnya (4, 3).
  3. Baris 5: (2, 1) dan (1, 2). Kedua dimensi masing-masing memuat satu angka satu, sehingga saling dikembangkan menjadi (2, 2).

Tabel berikut merangkum hasilnya:

Bentuk ABentuk BHasil broadcastAlasan singkat
(3, 1)(1, 4)(3, 4)1 dikembangkan mengikuti pasangannya
(4, 3)(3,)(4, 3)bentuk pendek dilengkapi dari depan
(2, 1)(1, 2)(2, 2)setiap 1 mengikuti pasangannya

Membaca Pesan Error Bentuk Tidak Cocok #

Bila ada sepasang dimensi yang tidak memenuhi aturan di atas, np.broadcast_shapes melempar ValueError dengan pesan yang menunjuk argumen yang bertabrakan.

python
import numpy as np

try:
    np.broadcast_shapes((2, 3), (4,))
except ValueError as e:
    print("ValueError:", e)

Output yang Dihasilkan:

text
ValueError: shape mismatch: objects cannot be broadcast to a single shape.  Mismatch is between arg 0 with shape (2, 3) and arg 1 with shape (4,).

Cara membacanya:

  1. shape mismatch: objects cannot be broadcast to a single shape.: tidak ada satu bentuk hasil yang bisa memuat kedua bentuk tersebut.
  2. Mismatch is between arg 0 with shape (2, 3) and arg 1 with shape (4,): NumPy menunjuk pasangan yang bertabrakan beserta bentuk aslinya. Dimensi terakhir 3 melawan 4 tidak sama, dan tak satu pun bernilai satu, sehingga aturan broadcasting gagal.
  3. Perbaikan yang lazim: pastikan maksud kita, lalu sesuaikan bentuk dengan np.newaxis, np.expand_dims, atau reshape — bukan dengan mengubah datanya.

Daftar Periksa Praktis #

Sebelum menulis operasi antar array, jalankan daftar ini:

  1. Cetak a.shape dan b.shape untuk operasi yang baru pertama kali ditulis.
  2. Bila a.shape == b.shape, operasi element-wise aman dijalankan.
  3. Bila berbeda, bandingkan dimensi dari belakang: sama, salah satu bernilai satu, atau salah satu sudah habis.
  4. Hitung bentuk hasil dengan np.broadcast_shapes(a.shape, b.shape) sebelum operasi berat dijalankan.
  5. Bila ValueError muncul, baca bagian Mismatch is between ... untuk menemukan pasangan dimensi yang bertabrakan, lalu perbaiki bentuk dengan np.newaxis, np.expand_dims, atau reshape.

Catatan: np.resize vs reshape #

reshape hanya menata ulang elemen; jumlah elemen tidak boleh berubah. Bila bentuk tujuan membutuhkan jumlah elemen yang berbeda, numpy menolak permintaan itu dengan ValueError. np.resize berperilaku lain: ia mengembalikan array baru dengan ukuran yang diminta — bila ukuran baru lebih besar, data lama diulang untuk mengisi sisa tempat; bila lebih kecil, data dipotong:

python
import numpy as np

a = np.arange(6)
try:
    a.reshape(4, 2)
except ValueError as e:
    print("ValueError:", e)
print(np.resize(a, 8))
print(np.resize(a, 3))

Output yang Dihasilkan:

text
ValueError: cannot reshape array of size 6 into shape (4,2)
[0 1 2 3 4 5 0 1]
[0 1 2]

Baris demi baris:

  1. Baris 4-7: reshape(4, 2) membutuhkan 8 elemen sedangkan a hanya memuat 6; numpy memunculkan ValueError yang pesannya menyebut ukuran array dan bentuk tujuan.
  2. Baris 8: np.resize(a, 8) mengulang data [0 1 2 3 4 5] hingga terisi 8 elemen: [0 1 2 3 4 5 0 1].
  3. Baris 9: np.resize(a, 3) meminta ukuran lebih kecil, sehingga data dipotong menjadi [0 1 2].

Perlu diingat: np.resize mengembalikan array baru yang berdiri sendiri, bukan view, sehingga a tetap utuh setelah pemanggilan.