Ketika hasil perhitungan seharusnya persis — indeks permutasi, hasil konversi dtype, penyalinan data, atau jumlah elemen yang dihitung dari panjang list — perbandingan yang tepat adalah np.testing.assert_array_equal. Fungsi ini menuntut kesamaan bentuk dan nilai pada setiap elemen, lalu melaporkan letak ketidaksesuaian secara rinci bila ada yang meleset.
Bab ini membedah semantik “persis” milik assert_array_equal: apa saja yang diperiksa, bagaimana nan diperlakukan, serta dua aturan penting di era NumPy 2 — parameter strict=True untuk pemeriksaan dtype dan penolakan broadcasting pada shape. Pembanding yang bertoleransi dibahas terpisah pada Chapter assert_allclose.
Semantik Kesamaan Persis #
assert_array_equal(actual, desired) lulus hanya jika kedua array memiliki shape sama dan setiap elemennya identik. Satu elemen saja yang berbeda membuat fungsi memunculkan AssertionError dengan laporan yang terperinci:
import numpy as np
from numpy.testing import assert_array_equal
hasil = np.array([85, 90, 78])
target = np.array([85, 91, 78])
try:
assert_array_equal(hasil, target)
print("lulus")
except AssertionError as e:
print("AssertionError:", e)Output yang Dihasilkan:
AssertionError:
Arrays are not equal
Mismatched elements: 1 / 3 (33.3%)
Max absolute difference among violations: 1
Max relative difference among violations: 0.01098901
ACTUAL: array([85, 90, 78])
DESIRED: array([85, 91, 78])Mari kita bedah:
- Baris 3-4:
hasildantargetberbeda pada satu elemen — nilai90melawan91di posisi kedua. - Laporan kesalahan:
Mismatched elements: 1 / 3 (33.3%)menghitung berapa banyak elemen yang tidak sama, sementara dua baris berikutnya mengukur selisih maksimum — absolut1dan relatif0.0109. Untuk data integer, selisih sebesar ini berarti logika yang salah, bukan galat pembulatan. - Baris
ACTUALdanDESIRED: kedua array dicetak berdampingan sehingga posisi elemen yang menyimpang langsung terlihat.
Perlu ditegaskan bahwa ketika pengujian lulus, fungsi ini tidak mencetak apa pun. Keheningan setelah pemanggilan adalah tanda keberhasilan; laporan panjang hanya muncul saat gagal.
Perilaku terhadap NaN #
nan tidak sama dengan apa pun — bahkan dengan dirinya sendiri — dan di sinilah assert_array_equal berbeda dari perbandingan biasa. Fungsi testing ini memperlakukan nan sebagai angka: nan pada posisi yang sama dianggap sama:
import numpy as np
from numpy.testing import assert_array_equal
sensor_a = np.array([22.1, np.nan, 23.4])
sensor_b = np.array([22.1, np.nan, 23.4])
print("sensor_a == sensor_b ->", sensor_a == sensor_b)
print("np.array_equal ->", np.array_equal(sensor_a, sensor_b))
assert_array_equal(sensor_a, sensor_b)
print("assert_array_equal -> lulus")Output yang Dihasilkan:
sensor_a == sensor_b -> [ True False True]
np.array_equal -> False
assert_array_equal -> lulusBedah baris demi baris:
- Baris 6: perbandingan
==mengikuti sifat aslinan: elemen kedua bernilaiFalsemeskipun kedua sisi sama-samanan. - Baris 7:
np.array_equalsecara bawaan memakai semantik yang sama (equal_nan=False), sehingga mengembalikanFalse— dua array yang identik dianggap berbeda hanya karena adanan. - Baris 8-9:
assert_array_equalmenolak semantik itu demi keperluan pengujian:nanpada posisi yang sama dianggap cocok, dan pemanggilan lulus tanpa error.
Parameter strict=True #
Secara bawaan, assert_array_equal tidak mempedulikan dtype: array int64 dan float64 dengan nilai sama dianggap lolos. Untuk pengujian yang juga menuntut tipe data sama, NumPy menyediakan parameter strict=True:
import numpy as np
from numpy.testing import assert_array_equal
utuh = np.array([1, 2, 3])
pecah = np.array([1.0, 2.0, 3.0])
try:
assert_array_equal(utuh, pecah)
print("int64 vs float64: lulus")
except AssertionError:
print("int64 vs float64: tidak lulus")
try:
assert_array_equal(utuh, pecah, strict=True)
print("strict=True: lulus")
except AssertionError as e:
print("strict=True: AssertionError")Output yang Dihasilkan:
int64 vs float64: lulus
strict=True: AssertionErrorBedah baris demi baris:
- Baris 3-4: kedua array memuat nilai yang sama persis, tetapi dtype-nya berbeda —
int64melawanfloat64. - Baris 6-9: tanpa
strict, pengujian lulus karena nilai elemennya memang sama; dtype dianggap detail yang boleh berbeda. - Baris 10-13: dengan
strict=True, kesamaan dtype menjadi syarat; pesan kesalahannya eksplisit:(dtypes int64, float64 mismatch). Blokexceptmencetak keterangan singkat karena isi pesan lengkapnya sudah kita kenal dari pola blok pertama.
Parameter strict juga mematikan perlakuan khusus terhadap scalar, sehingga pembanding menjadi sepenuhnya ketat: nilai, shape, dan dtype harus sama.
Shape Harus Sama Persis #
Sesuai namanya, assert_array_equal menuntut shape yang identik — perbandingan ini tidak melakukan broadcasting. Array (3, 1) dan (3,) memuat nilai yang sama, tetapi pengujian tetap menolaknya:
import numpy as np
from numpy.testing import assert_array_equal
kolom = np.array([1.0, 2.0, 3.0]).reshape(3, 1)
baris = np.array([1.0, 2.0, 3.0])
print("shape kolom:", kolom.shape, "| shape baris:", baris.shape)
try:
assert_array_equal(kolom, baris)
except AssertionError as e:
print("AssertionError:", e)Output yang Dihasilkan:
shape kolom: (3, 1) | shape baris: (3,)
AssertionError:
Arrays are not equal
(shapes (3, 1), (3,) mismatch)
ACTUAL: array([[1.],
[2.],
[3.]])
DESIRED: array([1., 2., 3.])Mari kita telaah:
- Baris 3-5:
kolomberbentuk(3, 1)hasilreshape, sedangkanbarisberbentuk(3,); secara aritmetika keduanya bisa di-broadcast, tetapi pengujian bukan tempat broadcasting. - Laporan kesalahan: baris
(shapes (3, 1), (3,) mismatch)menunjuk ketidakcocokan bentuk secara langsung — sebelum nilai mana pun dibandingkan. - Baris
ACTUALdanDESIRED: penyajian kedua array memperlihatkan perbedaan dimensi yang sesungguhnya, sesuatu yang tidak terlihat dari daftar angkanya saja.
Tabel berikut merangkum perilaku ketiga mode perbandingan yang telah kita uji:
| Perbandingan | Nilai sama | Shape berbeda | dtype berbeda | nan di posisi sama |
|---|---|---|---|---|
a == b | per elemen | broadcast | broadcast | False |
np.array_equal(a, b) | satu boolean | False | diabaikan | False |
assert_array_equal(a, b) | diam (lulus) | AssertionError | diabaikan | lulus |
assert_array_equal(a, b, strict=True) | diam (lulus) | AssertionError | AssertionError | lulus |
Pola pemilihan yang bisa dipakai: pilih assert_array_equal untuk hasil yang secara matematis harus persis, tambahkan strict=True ketika dtype bagian dari kontrak fungsi, dan pindah ke assert_allclose segera setelah hasil perhitungan menyentuh floating point. Contoh perancangan kasus uji yang menyatukan keduanya disusun pada Chapter Pengujian Operasi Numerik.