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.