6.4. Dtyper

Elementtypen för en ndarray är dess dtype. Dtypen bestämmer tre saker på en gång: hur många byte varje element upptar, hur byten tolkas och vilket värdeintervall arrayen kan lagra. Att välja rätt dtype är det enskilt viktigaste beslutet som påverkar RAM-användningen på kameran.

6.4.1. De dtyper som stöds

numpy på kameran stöder en liten uppsättning dtyper:

dtype

byte

intervall

uint8

1

0 till 255

int8

1

-128 till 127

uint16

2

0 till 65 535

int16

2

-32 768 till 32 767

float

4

IEEE 754 enkel precision

bool

1

True / False

Det finns ingen int32 eller int64, och OpenMV:s ulab-bygge aktiverar inte den valfria complex-dtypen.

Välj den typ som matchar hårdvaran som producerade datan. Ett 8-bitars ADC-sampel vill ha uint8; ett 12-bitars ADC-sampel ryms i uint16; en luminanspixel från en gråskalekamera ryms i uint8 – vilket sparar fyra gånger så mycket RAM som standardvärdet float skulle kosta.

6.4.2. Standard-dtypen

Standard-dtypen för varje konstruktor på Skapa arrayer är float. Det är sällan vad applikationen vill ha när den hanterar sensordata. Ange dtype= explicit närhelst den naturliga bredden är mindre:

sensor = np.array(samples, dtype=np.uint16)

Att åter-omsluta en heltalsarray utan ett dtype=-argument kopierar och konverterar till float, vilket både kostar tid och RAM. När prestanda är viktigt, namnge dtypen.

6.4.3. Dtypen för en befintlig array

dtype läser tillbaka arrayens dtype som den heltalstypkod som arrayen bär internt:

a = np.array([1, 2, 3], dtype=np.uint8)
print(a.dtype)            # 66 (the integer value of ``'B'``)

Typkodsheltalen matchar konstanterna som exponeras på numpy-modulen – numpy.uint8, numpy.int8, numpy.uint16, numpy.int16, numpy.float, numpy.bool – så att jämföra dtypen mot modulkonstanten är hur ett skript förgrenar sig på vad en array innehåller:

if a.dtype == np.uint8:
    ...  # uint8 branch

6.4.4. Regler för uppkonvertering

Två arrayer med olika dtyper kan vara operander till samma operator. numpy väljer resultattypen enligt en kort tabell:

vänster

höger

resultat

uint8

int8

int16

uint8

int16

int16

uint8

uint16

uint16

int8

int16

int16

int8

uint16

uint16

uint16

int16

float

valfri

float

float

Raden uint16 / int16 befordras direkt till float eftersom numpy på kameran inte har någon 32-bitars heltals-dtype.

När en binär operator har en Python-skalär på ena sidan konverteras skalären till en enelementsarray av den minsta lämpliga dtypen: 123 blir en uint8-array, -1000 blir int16, en Python-float blir float.

6.4.5. Heltalsspill slår runt

Operationer på två arrayer med samma heltals-dtype behåller den dtypen, även när resultatet spiller över. Överföringen släpps tyst:

a = np.array([200, 200], dtype=np.uint8)
b = np.array([100, 100], dtype=np.uint8)
print(a + b)

Utdata:

array([44, 44], dtype=uint8)

Resultatet är 300 mod 256 == 44. När ett mellanresultat behöver större intervall än indata-dtypen tillåter, casta först:

c = np.array(a, dtype=np.uint16) + b
# array([300, 300], dtype=uint16)

Denna regel gäller för varje heltalsoperator – +, -, *, //, %, &, |, ^. Float-arrayer spiller aldrig över (de befordras till oändlighet i stället), så cast-tricket behövs bara i heltalsfallet.