6.3. Stvaranje polja

Svaki primjer na ostalim ovim stranicama započinje s ndarray koji je već u ruci. Ova stranica je katalog načina na koje to polje nastaje. Postoje četiri obitelji konstruktora:

  • Iz Python iterabilnog objekta – uobičajeni oblik literala / liste / torke.

  • Unaprijed popunjeno na zadanom obliku – nule, jedinice, konstantna vrijednost, jedinična matrica.

  • Generirano kao niz – vrijednosti u rasponu ili ravnomjerno razmaknute.

  • Omatanje međuspremnika koji je već u RAM-u – slučaj periferije.

Svaki konstruktor prima ključnu riječ dtype= i zadano koristi float. Podaci senzora gotovo uvijek žele manji dtype od zadanog.

Svaki primjer u nastavku započinje s:

from ulab import numpy as np

6.3.1. Iz Python iterabilnog objekta

array() gradi ndarray iz bilo kojeg iterabilnog objekta brojeva:

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

Izlaz:

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

Ugniježđeni iterabilni objekti proizvode višedimenzionalna polja. Unutarnji iterabilni objekti moraju svi imati istu duljinu, inače se podiže ValueError

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

Postojeći ndarray također je valjan ulaz; array() uvijek kopira. Da biste izbjegli kopiranje kad nije potrebno, koristite asarray()

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

6.3.2. Unaprijed popunjeno na zadanom obliku

Kada je ciljani oblik poznat, ali sadržaj još nije, alocirajte međuspremnik unaprijed i zapišite u njega kasnije:

  • zeros() – popunjeno nulama.

  • ones() – popunjeno jedinicama.

  • full() – popunjeno zadanom vrijednošću.

  • empty() – alias za zeros() (ulab ne ostavlja međuspremnik neinicijaliziranim).

  • eye()N-puta-M matrica nalik jediničnoj s jedinicama na k-toj dijagonali.

  • diag() – dijagonalna matrica iz vektora, ili dijagonala matrice.

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

Argument shape je ili jedan cijeli broj (za 1-D polje) ili torka.

6.3.3. Generirano kao niz

  • arange() – ravnomjerno razmaknute vrijednosti poput ugrađenog range(), ali uvijek vraća ndarray

    np.arange(0, 10, 2)            # array([0, 2, 4, 6, 8])
    
  • linspace()num ravnomjerno razmaknutih točaka između dvije granice, s uključenom gornjom granicom kada je endpoint=True

    np.linspace(0, 1, num=11)      # 0.0, 0.1, ..., 1.0
    
  • logspace() – geometrijski razmaknute točke. start i stop su eksponenti, ne krajnje točke; rezultat ide od base ** start do base ** stop

    np.logspace(0, 3, num=4)       # 1.0, 10.0, 100.0, 1000.0
    
  • meshgrid() – gradi dvije matrice koordinata iz dva 1-D polja kako bi se funkcija po pikselu f(x, y) mogla evaluirati nad cijelom mrežom u jednom vektoriziranom pozivu. Za x-vektor duljine W i y-vektor duljine H, meshgrid vraća dvije H-puta-W matrice: X je x-vektor ponovljen niz svaki redak, Y je y-vektor ponovljen kroz svaki stupac, pa je X[i, j] x-koordinata, a Y[i, j] y-koordinata ćelije u retku i i stupcu 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) zatim evaluira funkciju u svakoj ćeliji mreže u jednom izrazu. Karta udaljenosti od središta nad sličicom (H, W), primjerice, jest np.sqrt((X - cx)**2 + (Y - cy)**2) nad matricama koje je vratio meshgrid().

6.3.4. Spajanje

concatenate() spaja torku polja duž postojeće osi:

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)

Svi ulazi moraju dijeliti isti dtype i ndim te se podudarati po svakoj osi osim one po kojoj se spaja. concatenate() alocira novo polje dovoljno veliko da primi svaki ulaz i u njega kopira podatke, pa je to pravi alat za jednokratno spajanje polja koja već postoje; pogrešan je alat unutar petlje strujanja, gdje je obrazac jednom unaprijed alocirati odredište i u njega pisati putem dodjele isječaka.

6.3.5. Omatanje postojećeg međuspremnika

Najkorisniji konstruktor na kameri je frombuffer(). On ponovno tumači postojeći međuspremnik nalik bajtovima kao 1-D ndarray bez kopiranja ijednog bajta:

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

Pisanja kroz audio vidljiva su u buf i obratno. Odabrani dtype mora ravnomjerno dijeliti duljinu međuspremnika.

offset= preskače zaglavlje na početku međuspremnika; count= ograničava koliko se elemenata čita:

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

Ovo je pravi konstruktor kad god periferija predaje aplikaciji sirovi međuspremnik – ADC uzorci u bytearray, korisni teret povučen iz SPI. Bajtovi koje je periferija zapisala jesu polje.

Kada periferija zapisuje višebajtne vrijednosti redoslijedom bajtova koji CPU kamere ne čita izvorno, byteswap() obrće redoslijed bajtova svakog elementa kako bi se vrijednosti ispravno čitale. Zadano vraća novo polje; prosljeđivanje inplace=True mijenja izvor na licu mjesta.

frombuffer() rukuje samo dtypeovima koje numpy sam definira. Za periferije koje proizvode 32-bitne cjelobrojne uzorke, from_int32_buffer() i srodne funkcije pretvaraju u float u jednom prolazu.