Chapter-chapter sebelumnya memakai frasa “elemen demi elemen” tanpa kita definisikan secara resmi. Frasa itu — atau element-wise — adalah kontrak dasar semua operasi NumPy: setiap elemen operan pertama dipasangkan dengan elemen operan kedua pada posisi yang sama, dihitung, lalu hasilnya dikumpulkan menjadi array baru. Kontrak ini menjelaskan mengapa operasi array terasa seperti operasi angka tunggal, dan mengapa bentuk (shape) kedua operan menjadi syarat yang sering dipersoalkan.

Tiga hal yang kita pastikan di bab ini:

  • Pasangan bentuk yang sama dapat dioperasikan langsung, termasuk pada array 2-D.
  • dtype hasil mengikuti dtype operan yang lebih “tinggi”.
  • Pasangan bentuk yang tidak serasi melempar ValueError dengan pesan yang informatif.

Dua array berbentuk sama #

Bentuk yang sama membuat kontrak element-wise terpenuhi dengan pasangan yang sejajar satu-satu:

python
import numpy as np

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])
print(a + b)
print(a - b)
print(a * b)
print(a + np.array([0.5, 0.5, 0.5]))
print(a * 2)

Output yang Dihasilkan:

text
[11 22 33]
[ 9 18 27]
[10 40 90]
[10.5 20.5 30.5]
[20 40 60]
  1. Baris 5 (a + b): pasangan yang dihitung adalah 10+1, 20+2, 30+3 — posisi ke-0 dengan posisi ke-0, dan seterusnya.
  2. Baris 7 (a * b): perkalian menghasilkan 10, 40, 90; ingat, ini perkalian elemen demi elemen, bukan perkalian matriks.
  3. Baris 8 (a + np.array([0.5, 0.5, 0.5])): operan int64 bertemu float64. dtype hasil mengikuti dtype yang lebih “tinggi”, sehingga keluar float64 dan tampil sebagai [10.5 20.5 30.5].
  4. Baris 9 (a * 2): satu angka diperlakukan seragam untuk semua posisi — pratinjau kecil dari broadcasting.

Aturan dasarnya dapat dirangkum dalam tiga poin:

  1. Pasangkan elemen pada posisi yang sama, hitung, kumpulkan menjadi array baru.
  2. Bentuk kedua operan harus sama, atau serasi menurut aturan broadcasting.
  3. dtype hasil mengikuti dtype operan yang lebih tinggi (int + float menjadi float).

Operasi element-wise pada array dua dimensi #

Kontrak yang sama berlaku pada array multidimensi: pasangan yang dipadangkan ditentukan oleh indeks lengkapnya, misalnya [baris, kolom]:

python
import numpy as np

penjualan = np.array([[10, 20, 30],
                      [15, 25, 35]])
target = np.array([[8, 22, 28],
                   [12, 20, 40]])
print(penjualan - target)
print(penjualan + target)

Output yang Dihasilkan:

text
[[ 2 -2  2]
 [ 3  5 -5]]
[[18 42 58]
 [27 45 75]]
  1. Baris 3-6: dua array 2-D berbentuk (2, 3) — dua cabang, tiga produk.
  2. Baris 7 (penjualan - target): setiap sel dihitung dengan pasangan sel yang letaknya sama: [0,0] dengan [0,0] memberi 10-8 = 2, [0,1] dengan [0,1] memberi 20-22 = -2. Selisih positif berarti melampaui target.
  3. Baris 8 (penjualan + target): penjumlahan per sel memberi total gabungan; bentuk hasil selalu mengikuti bentuk operan, tetap (2, 3).

Ketika bentuk tidak cocok: ValueError #

Kontrak element-wise menuntut NumPy tahu cara memasangkan setiap elemen. Ketika bentuk operan tidak dapat dipasangkan dan tidak serasi menurut broadcasting, operasi dihentikan dengan ValueError:

python
import numpy as np

x = np.arange(3)
y = np.arange(4)
try:
    z = x + y
except ValueError as e:
    print("ValueError:", e)
matriks = np.ones((2, 3))
vektor = np.arange(4)
try:
    hasil = matriks + vektor
except ValueError as e:
    print("ValueError:", e)

Output yang Dihasilkan:

text
ValueError: operands could not be broadcast together with shapes (3,) (4,)
ValueError: operands could not be broadcast together with shapes (2,3) (4,)
  1. Baris 5-8: x berbentuk (3,) dan y berbentuk (4,). Elemen keempat y tidak punya pasangan, dan NumPy tidak mau menebak — pesan kesalahan menyebut kedua bentuk secara eksplisit sehingga sumber masalah mudah ditemukan.
  2. Baris 9-14: bentuk (2, 3) melawan (4,) juga gagal. Perhatikan pesannya memakai kata broadcast: NumPy sebenarnya sudah mencoba mencocokkan bentuk keduanya sebelum menyerah.

Tabel kecil ini memetakan pasangan bentuk yang bisa langsung dioperasikan:

Bentuk ABentuk BHasil
(3,)(3,)operasi element-wise berjalan
(2, 3)(2, 3)operasi element-wise berjalan
(3,)(4,)ValueError
(2, 3)(4,)ValueError