Operasi array yang paling sering ditulis hanyalah array berjumpa satu angka: menaikkan seluruh harga sepuluh persen, mengonversi seluruh suhu ke Fahrenheit, atau mengurangi seluruh stok satu unit. NumPy memperlakukan angka tunggal itu sebagai scalar — array tanpa dimensi berbentuk () — dan aturan broadcasting memastikan scalar cocok dengan bentuk apa pun.

Bab ini menuntaskan tiga pertanyaan:

  • Bagaimana bentuk dan dtype hasil ketika array dikalikan scalar?
  • Mengapa bentuk () kompatibel dengan semua bentuk?
  • Apakah operasi dengan scalar menyalin data?

Mengalikan seluruh array dengan satu angka #

Kenaikan harga sepuluh persen berarti mengalikan tiap harga dengan 1.1:

python
import numpy as np

harga = np.array([10000, 15000, 20000, 25000])
hasil = harga * 1.1

print(hasil)
print(hasil.dtype)

Output yang Dihasilkan:

text
[11000. 16500. 22000. 27500.]
float64
  1. Baris 3 (harga): array (4,) dengan dtype int64 karena seluruh elemennya bilangan bulat.
  2. Baris 4 (harga * 1.1): scalar 1.1 diperlakukan sebagai array berbentuk (); perkalian berjalan per elemen dan menghasilkan array baru.
  3. Baris 6-7: hasil memakai float64 — NumPy mempromosikan int64 lawan float64 Python menjadi float64, sehingga nilai pecahan hasil kenaikan sepuluh persen tetap tersimpan utuh.

Scalar adalah array berbentuk () #

Scalar Python biasa punya ndim nol dan bentuk tupel kosong. Kita periksa langsung, lalu uji dengan np.broadcast_shapes:

python
import numpy as np

print(np.ndim(1.1))
print(np.shape(1.1))
print(np.broadcast_shapes((3, 4), ()))
print(np.broadcast_shapes((), (7,)))
print(np.shape(np.float64(2.5)))

Output yang Dihasilkan:

text
0
()
(3, 4)
(7,)
()
  1. Baris 3-4: 1.1 memiliki nol dimensi dan bentuk () — sebuah tupel kosong, bukan (1,) maupun (0,).
  2. Baris 5-6: () berpasangan dengan (3, 4) menghasilkan (3, 4); berpasangan dengan (7,) menghasilkan (7,). Bentuk hasil selalu mengikuti bentuk pasangannya.
  3. Baris 7 (np.float64(2.5)): scalar yang membungkus nilai NumPy pun berbentuk () — perlakuan broadcasting identik.

Alasan kompatibilitasnya sederhana: aturan kedua broadcasting memeriksa pasangan dimensi, sedangkan bentuk () tidak memiliki satu pun dimensi untuk diperiksa. Tanpa pasangan yang bisa gagal, scalar lolos terhadap bentuk apa pun.

Memori: scalar disimpan satu kali #

Satu pertanyaan wajar: apakah a + 5.0 membuat array perantara berisi lima berulang? Kita ukur nbytes hasilnya:

python
import numpy as np

a = np.zeros(3)
b = a + 5.0

print(a.nbytes, b.nbytes)
print(np.broadcast_shapes(a.shape, ()))

Output yang Dihasilkan:

text
24 24
(3,)
  1. Baris 4-5 (b = a + 5.0): operasi menghasilkan array baru (3,).
  2. Baris 7: a dan b sama-sama 24 byte. Scalar 5.0 disimpan di satu lokasi memori dan dibaca ulang NumPy pada setiap langkah perhitungan — tidak ada array perantara berisi lima berulang.
  3. Baris 8: bentuk hasil (3,) menegaskan kembali aturan bentuk hasil pada bab sebelumnya.

Ketika array berisi satu juta elemen dijumlahkan dengan 5.0, yang terjadi adalah satu juta kali pembacaan nilai 5.0 yang sama, bukan penyalinan satu juta angka lima.

Hati-hati dengan makna * pada list Python #

Tabel berikut merangkum perilaku operasi scalar:

EkspresiBentuk hasilCatatan
harga * 1.1sama dengan bentuk hargadtype mengikuti aturan promosi tipe
matriks + 10sama dengan bentuk matriksscalar cocok dengan ndim berapa pun
np.broadcast_shapes((), (7,))(7,)bentuk () selalu mengikuti pasangannya