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 |
|---|---|---|
|
1 |
0 till 255 |
|
1 |
-128 till 127 |
|
2 |
0 till 65 535 |
|
2 |
-32 768 till 32 767 |
|
4 |
IEEE 754 enkel precision |
|
1 |
|
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 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
valfri |
|
|
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.