6.2. Ndarray

ndarray adalah tipe yang menyimpan data numerik di numpy. Ini adalah dua hal sekaligus: satu blok data yang dikemas dan sebuah deskriptor kecil di depan blok tersebut yang menjelaskan cara membacanya.

6.2.1. Di dalam kotak

Blok data menyimpan setiap elemen array berturut-turut, tanpa tambahan apa pun di antaranya. Setiap elemen menempati jumlah byte yang sama -- satu untuk array nilai uint8, dua untuk uint16, empat untuk float. Array uint8 dengan 256 elemen tepat 256 byte data; 256 angka yang sama dalam Python list memakan satu kilobyte -- satu slot 32-bit per elemen terlepas dari berapa sedikit bit yang sebenarnya dibutuhkan nilai tersebut.

Deskriptor mencatat apa yang dimaksud oleh blok tersebut. Lima nilai sudah cukup untuk mendeskripsikan array persegi panjang apa pun, tidak peduli berapa banyak dimensinya:

  • dtype -- tipe elemen. Menentukan berapa byte yang ditempati setiap elemen dan rentang nilai yang dapat disimpan (dibahas di Dtype).

  • itemsize -- lebar byte satu elemen, yang diturunkan dari dtype.

  • ndim -- jumlah dimensi (1 untuk vektor, 2 untuk matriks, 3 untuk volume, hingga 4).

  • shape -- ukuran sepanjang setiap dimensi sebagai tuple.

  • strides -- cara melangkah melalui blok data untuk menelusuri setiap sumbu. Dibahas di Shape dan strides.

Itulah saja. Setiap jalur cepat di numpy -- aritmatika, reduksi, broadcasting, slicing -- bekerja langsung dari lima nilai tersebut ditambah pointer data, tanpa overhead Python per elemen.

6.2.2. Apa yang diperoleh dari desain ini

Tiga properti muncul dari "blok yang dikemas + deskriptor kecil" dan mendefinisikan bagaimana sisa bagian ini berperilaku.

Matematika per elemen berjalan sebagai satu panggilan. a + b antara dua array dengan bentuk yang cocok menjumlahkan dua buffer dan menulis yang ketiga, semuanya dalam satu panggilan library. np.sin(a) melakukan hal yang sama untuk sinus setiap elemen. Operator aritmatika, perbandingan, dan bitwise semuanya bekerja dengan cara ini.

Melihat data yang sama dengan cara berbeda itu gratis. Meminta sub-wilayah dari array, atau data yang sama dengan tata letak berbeda, tidak memindahkan byte apa pun. Operasi ini mengembalikan deskriptor baru yang menunjuk ke blok data yang sama. Hasilnya disebut view -- jendela kedua ke buffer yang sama. Penulisan melalui view menulis ke sumber.

Bentuk campuran tetap berfungsi. Array yang lebih pendek terhadap yang lebih panjang, baris terhadap matriks, kolom terhadap baris -- numpy menyelaraskannya melalui broadcasting, sekumpulan aturan kecil yang menentukan sumbu pendek mana yang direntangkan untuk menyamai yang panjang. Perentangan bersifat virtual; tidak ada data yang diduplikasi.

6.2.3. Apa yang menjadi biaya desain ini

Dua pembatasan mengikuti desain yang sama.

Setiap elemen memiliki tipe yang sama. Sebuah list dapat menyimpan int di sebelah str di sebelah list tiga int lagi; ndarray tidak bisa. Dtype ditetapkan pada waktu konstruksi. Halaman Dtype mencakup sekumpulan tipe kecil yang didukung numpy dan aturan yang muncul dari penetapan satu tipe.

Menumbuhkan array tidak gratis. Sebuah list menyimpan slot cadangan di ujungnya dan mendukung .append secara murah. ndarray berukuran tepat sesuai kebutuhan; menambahkan elemen berarti mengalokasikan buffer baru yang lebih besar dan menyalin isi lama ke dalamnya. Tidak ada metode append(), dengan sengaja. Pola yang benar pada kamera adalah pra-alokasi tujuan pada ukuran akhirnya dan mengisi-nya; Performa mencakup teknik tersebut.

Dengan buffer bertipe yang dikemas untuk data, deskriptor kecil untuk metadata, dan tiga jaminan perilaku (matematika per elemen yang cepat, tampilan alternatif tanpa salinan dari data yang sama, dan bentuk yang di-broadcast), ndarray adalah fondasi tempat sisa bab ini bertumpu. Bagaimana sebuah array benar-benar terbentuk -- dari literal, dari alokasi pra-terisi, dari buffer periferal -- adalah pertanyaan praktis berikutnya.