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
ValueErrordengan pesan yang informatif.
Dua array berbentuk sama #
Bentuk yang sama membuat kontrak element-wise terpenuhi dengan pasangan yang sejajar satu-satu:
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:
[11 22 33]
[ 9 18 27]
[10 40 90]
[10.5 20.5 30.5]
[20 40 60]- Baris 5 (
a + b): pasangan yang dihitung adalah10+1,20+2,30+3— posisi ke-0 dengan posisi ke-0, dan seterusnya. - Baris 7 (
a * b): perkalian menghasilkan10,40,90; ingat, ini perkalian elemen demi elemen, bukan perkalian matriks. - Baris 8 (
a + np.array([0.5, 0.5, 0.5])): operan int64 bertemu float64. dtype hasil mengikuti dtype yang lebih “tinggi”, sehingga keluarfloat64dan tampil sebagai[10.5 20.5 30.5]. - Baris 9 (
a * 2): satu angka diperlakukan seragam untuk semua posisi — pratinjau kecil dari broadcasting.
Aturan dasarnya dapat dirangkum dalam tiga poin:
- Pasangkan elemen pada posisi yang sama, hitung, kumpulkan menjadi array baru.
- Bentuk kedua operan harus sama, atau serasi menurut aturan broadcasting.
- 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]:
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:
[[ 2 -2 2]
[ 3 5 -5]]
[[18 42 58]
[27 45 75]]- Baris 3-6: dua array 2-D berbentuk
(2, 3)— dua cabang, tiga produk. - Baris 7 (
penjualan - target): setiap sel dihitung dengan pasangan sel yang letaknya sama:[0,0]dengan[0,0]memberi10-8 = 2,[0,1]dengan[0,1]memberi20-22 = -2. Selisih positif berarti melampaui target. - 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:
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:
ValueError: operands could not be broadcast together with shapes (3,) (4,)
ValueError: operands could not be broadcast together with shapes (2,3) (4,)- Baris 5-8:
xberbentuk(3,)danyberbentuk(4,). Elemen keempatytidak punya pasangan, dan NumPy tidak mau menebak — pesan kesalahan menyebut kedua bentuk secara eksplisit sehingga sumber masalah mudah ditemukan. - 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 A | Bentuk B | Hasil |
|---|---|---|
(3,) | (3,) | operasi element-wise berjalan |
(2, 3) | (2, 3) | operasi element-wise berjalan |
(3,) | (4,) | ValueError |
(2, 3) | (4,) | ValueError |