6.3. Tömbök létrehozása

Ezeken az oldalakon a többi példa mind egy már kész ndarray-jel indul. Ez az oldal annak a katalógusa, hogy az a tömb hogyan jön létre. A konstruktoroknak négy családja van:

  • Python iterálhatóból – a szokásos literál / lista / tuple forma.

  • Adott alakra előre kitöltve – nullák, egyesek, egy konstans érték, egy egységmátrix.

  • Sorozatként generálva – tartományból vagy egyenletesen elosztott értékek.

  • Egy már a RAM-ban lévő puffer becsomagolása – a perifériás eset.

Minden konstruktor elfogad egy dtype= kulcsszót, és alapértelmezésben float-ot használ. Az érzékelőadatok szinte mindig kisebb dtype-ot igényelnek az alapértelmezettnél.

Az alábbi minden példa ezzel kezdődik:

from ulab import numpy as np

6.3.1. Python iterálhatóból

A array() bármely számokból álló iterálhatóból ndarray-t épít:

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

Kimenet:

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

A beágyazott iterálhatók többdimenziós tömböket hoznak létre. A belső iterálhatóknak mind azonos hosszúságúaknak kell lenniük, különben ValueError keletkezik:

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

Egy már létező ndarray szintén érvényes bemenet; a array() mindig másol. Hogy elkerüld a másolást, amikor arra nincs szükség, használd a asarray()-t:

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

6.3.2. Adott alakra előre kitöltve

Amikor a célalak ismert, de a tartalom még nem, foglald le a puffert előre, és írj bele később:

  • zeros() – nullákkal kitöltve.

  • ones() – egyesekkel kitöltve.

  • full() – egy adott értékkel kitöltve.

  • empty() – a zeros() aliasa (az ulab nem hagyja a puffert inicializálatlanul).

  • eye() – egységmátrixhoz hasonló N-szer M-es mátrix, egyesekkel a k-adik átlón.

  • diag() – átlós mátrix egy vektorból, vagy egy mátrix átlója.

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

A shape argumentum vagy egyetlen egész szám (1-D tömbhöz), vagy egy tuple.

6.3.3. Sorozatként generálva

  • arange() – egyenletesen elosztott értékek a beépített range()-hez hasonlóan, de mindig ndarray-t adva vissza:

    np.arange(0, 10, 2)            # array([0, 2, 4, 6, 8])
    
  • linspace()num darab egyenletesen elosztott pont két határ között, ahol a felső határ beleszámít, ha endpoint=True

    np.linspace(0, 1, num=11)      # 0.0, 0.1, ..., 1.0
    
  • logspace() – geometriailag elosztott pontok. A start és a stop kitevők, nem végpontok; az eredmény base ** start-tól base ** stop-ig fut:

    np.logspace(0, 3, num=4)       # 1.0, 10.0, 100.0, 1000.0
    
  • meshgrid() – két koordinátamátrixot épít két 1-D tömbből, így egy képpontonkénti f(x, y) függvény egyetlen vektorizált hívással kiértékelhető egy egész rácson. Egy W hosszúságú x-vektor és egy H hosszúságú y-vektor esetén a meshgrid két H-szer W-es mátrixot ad vissza: az X az x-vektor minden sorban lefelé ismételve, az Y az y-vektor minden oszlopon át ismételve, így X[i, j] az x-koordináta és Y[i, j] az y-koordináta az i sorban és j oszlopban lévő cellában:

    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]]
    

    Az f(X, Y) ezután egyetlen kifejezésben kiértékeli a függvényt a rács minden cellájában. Egy (H, W) képkockára vetített, középponttól vett távolságot mutató térkép például np.sqrt((X - cx)**2 + (Y - cy)**2) a meshgrid() által visszaadott mátrixokon.

6.3.4. Összefűzés

A concatenate() egy tömb-tuple-t fűz össze egy meglévő tengely mentén:

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)

Minden bemenetnek azonos dtype-pal és ndim-mel kell rendelkeznie, és minden tengelyen egyeznie kell, kivéve az összefűzés tengelyét. A concatenate() egy friss, az összes bemenet befogadására elég nagy tömböt foglal le, és bemásolja az adatokat, így a megfelelő eszköz a már létező tömbök egyszeri összefűzéséhez; rossz eszköz egy streamelő cikluson belül, ahol a célt egyszer előre lefoglalni és szeletértékadáson keresztül belőle írni a követendő minta.

6.3.5. Egy meglévő puffer becsomagolása

A kamerán a leghasznosabb konstruktor a frombuffer(). Ez egy meglévő bájtszerű puffert egy 1-D ndarray-ként értelmez újra, anélkül, hogy egyetlen bájtot is másolna

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

Az audio-n keresztüli írások láthatóak a buf-ban, és fordítva. A kiválasztott dtype-nak egyenletesen kell osztania a puffer hosszát.

Az offset= átugor egy fejlécet a puffer elején; a count= korlátozza, hány elem olvasódik be:

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

Ez a megfelelő konstruktor, valahányszor egy periféria nyers puffert ad át az alkalmazásnak – ADC-mintákat egy bytearray-ben, egy SPI-ból kihúzott hasznos terhet. A periféria által írt bájtok alkotják a tömböt.

Amikor egy periféria többbájtos értékeket olyan bájtsorrendben ír, amelyet a kamera CPU-ja nem natívan olvas, a byteswap() minden elem bájtsorrendjét megfordítja, hogy az értékek helyesen olvasódjanak. Alapértelmezésben új tömböt ad vissza; az inplace=True átadása a forrást helyben módosítja.

A frombuffer() csak azokat a dtype-okat kezeli, amelyeket maga a numpy definiál. Azon perifériákhoz, amelyek 32 bites egész mintákat állítanak elő, a from_int32_buffer() és társai egyetlen menetben float-tá konvertálnak.