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.