6.3. Membuat array

Setiap contoh di halaman-halaman berikutnya dimulai dengan ndarray yang sudah tersedia. Halaman ini adalah katalog tentang bagaimana array tersebut dibuat. Ada empat keluarga konstruktor:

  • Dari iterable Python -- bentuk literal / list / tuple yang biasa.

  • Diisi sebelumnya dengan bentuk tertentu -- nol, satu, nilai konstan, matriks identitas.

  • Dibuat sebagai sekuens -- nilai berurutan atau berjarak merata.

  • Membungkus buffer yang sudah ada di RAM -- kasus periferal.

Setiap konstruktor menerima kata kunci dtype= dan secara default menggunakan float. Data sensor hampir selalu membutuhkan dtype yang lebih kecil dari default.

Setiap contoh di bawah dimulai dengan:

from ulab import numpy as np

6.3.1. Dari iterable Python

array() membangun ndarray dari iterable angka apa pun:

a = np.array([1, 2, 3, 4])
print(a)

Output:

array([1.0, 2.0, 3.0, 4.0], dtype=float)

Iterable bersarang menghasilkan array multidimensi. Iterable dalam harus semuanya memiliki panjang yang sama, atau ValueError akan dimunculkan:

m = np.array([[1, 2, 3],
              [4, 5, 6]], dtype=np.uint8)

ndarray yang sudah ada juga merupakan masukan yang valid; array() selalu menyalin. Untuk menghindari salinan ketika tidak diperlukan, gunakan asarray()

b = np.asarray(a, dtype=np.float)   # same dtype -> no copy

6.3.2. Diisi sebelumnya dengan bentuk tertentu

Ketika bentuk target diketahui tetapi isinya belum, alokasikan buffer terlebih dahulu dan isi nanti:

  • zeros() -- diisi dengan nol.

  • ones() -- diisi dengan satu.

  • full() -- diisi dengan nilai tertentu.

  • empty() -- alias untuk zeros() (ulab tidak membiarkan buffer tidak terinisialisasi).

  • eye() -- matriks N-kali-M mirip identitas dengan satu pada diagonal ke-k.

  • diag() -- matriks diagonal dari vektor, atau diagonal dari sebuah matriks.

np.zeros((3, 3))                   # 3x3 of zeros
np.ones(5, dtype=np.uint8)         # length-5 vector of ones
np.full((2, 3), 7, dtype=np.int8)  # 2x3, all 7
np.eye(4)                          # 4x4 identity
np.diag([1, 2, 3])                 # 3x3, [1, 2, 3] on the diagonal

Argumen shape berupa satu integer (untuk array 1-D) atau sebuah tuple.

6.3.3. Dibuat sebagai sekuens

  • arange() -- nilai berjarak merata seperti range() bawaan, tetapi selalu mengembalikan ndarray

    np.arange(0, 10, 2)            # array([0, 2, 4, 6, 8])
    
  • linspace() -- num titik berjarak merata antara dua batas, dengan batas atas disertakan ketika endpoint=True

    np.linspace(0, 1, num=11)      # 0.0, 0.1, ..., 1.0
    
  • logspace() -- titik-titik berjarak geometris. start dan stop adalah eksponen, bukan titik ujung; hasilnya berjalan dari base ** start hingga base ** stop

    np.logspace(0, 3, num=4)       # 1.0, 10.0, 100.0, 1000.0
    
  • meshgrid() -- membangun dua matriks koordinat dari dua array 1-D sehingga fungsi per-piksel f(x, y) dapat dievaluasi di seluruh grid dalam satu panggilan tervektorisasi. Dengan vektor x sepanjang W dan vektor y sepanjang H, meshgrid mengembalikan dua matriks H-kali-W: X adalah vektor x yang diulang di setiap baris, Y adalah vektor y yang diulang di setiap kolom, sehingga X[i, j] adalah koordinat x dan Y[i, j] adalah koordinat y dari sel pada baris i dan kolom j

    x = np.arange(4)            # [0, 1, 2, 3]
    y = np.arange(3)            # [0, 1, 2]
    X, Y = np.meshgrid(x, y)
    # X = [[0, 1, 2, 3],
    #      [0, 1, 2, 3],
    #      [0, 1, 2, 3]]
    # Y = [[0, 0, 0, 0],
    #      [1, 1, 1, 1],
    #      [2, 2, 2, 2]]
    

    f(X, Y) kemudian mengevaluasi fungsi di setiap sel grid dalam satu ekspresi. Peta jarak-dari-pusat pada bingkai (H, W), misalnya, adalah np.sqrt((X - cx)**2 + (Y - cy)**2) terhadap matriks yang dikembalikan oleh meshgrid().

6.3.4. Penggabungan

concatenate() menggabungkan tuple array sepanjang sumbu yang ada:

a = np.array([[1, 2], [3, 4]], dtype=np.uint8)
b = np.array([[5, 6]],         dtype=np.uint8)
np.concatenate((a, b), axis=0)
# array([[1, 2], [3, 4], [5, 6]], dtype=uint8)

Semua masukan harus berbagi dtype dan ndim yang sama, serta cocok di setiap sumbu selain sumbu penggabungan. concatenate() mengalokasikan array baru yang cukup besar untuk menampung setiap masukan dan menyalin data ke dalamnya, sehingga ini adalah alat yang tepat untuk penggabungan sekali jalan dari array yang sudah ada; ini bukan alat yang tepat di dalam loop streaming, di mana pra-alokasi tujuan sekali saja dan penulisan melalui penetapan slice adalah pola yang benar.

6.3.5. Membungkus buffer yang sudah ada

Konstruktor yang paling berguna pada kamera adalah frombuffer(). Ini menginterpretasi ulang buffer bytes-like yang ada sebagai ndarray 1-D tanpa menyalin satu byte pun:

buf = bytearray(8)
audio = np.frombuffer(buf, dtype=np.int16)
# 4 int16 samples, sharing memory with buf

Penulisan melalui audio terlihat di buf dan sebaliknya. dtype yang dipilih harus dapat membagi panjang buffer secara merata.

offset= melewatkan header di awal buffer; count= membatasi berapa banyak elemen yang dibaca:

np.frombuffer(buf, dtype=np.uint8, offset=2, count=4)

Ini adalah konstruktor yang tepat setiap kali periferal menyerahkan buffer mentah ke aplikasi -- sampel ADC dalam bytearray, payload yang diambil dari SPI. Byte yang ditulis periferal adalah arraynya.

Ketika periferal menulis nilai multi-byte dalam urutan byte yang tidak dapat dibaca secara native oleh CPU kamera, byteswap() membalik urutan byte setiap elemen sehingga nilai dapat dibaca dengan benar. Secara default mengembalikan array baru; melewatkan inplace=True memodifikasi sumber secara langsung.

frombuffer() hanya menangani dtype yang didefinisikan oleh numpy sendiri. Untuk periferal yang menghasilkan sampel integer 32-bit, from_int32_buffer() dan fungsi sejenis mengonversi ke float dalam satu langkah.