6.4. Dtypes#
Tip elementa ndarray je njegov dtype. Dtype odjednom određuje tri stvari: koliko bajtova zauzima svaki element, kako se bajtovi tumače i koji raspon vrijednosti polje može pohraniti. Odabir ispravnog dtypea najvažnija je pojedinačna odluka koja utječe na potrošnju RAM-a na kameri.
6.4.1. Podržani dtypeovi#
numpy na kameri podržava mali skup dtypeova:
dtype | bajtovi | raspon |
|---|---|---|
| 1 | 0 do 255 |
| 1 | -128 do 127 |
| 2 | 0 do 65.535 |
| 2 | -32.768 do 32.767 |
| 4 | IEEE 754 jednostruka preciznost |
| 1 |
|
Ne postoji int32 ni int64, a OpenMV-ova ulab verzija ne omogućuje opcionalni complex dtype.
Odaberite tip koji odgovara hardveru koji je proizveo podatke. 8-bitni ADC uzorak želi uint8; 12-bitni ADC uzorak stane u uint16; piksel svjetline iz kamere u sivim tonovima stane u uint8 – čime se štedi četiri puta više RAM-a nego što bi koštao zadani float.
6.4.2. Zadani dtype#
Zadani dtype svakog konstruktora na Stvaranje polja je float. To je rijetko ono što aplikacija želi pri rukovanju podacima senzora. Eksplicitno proslijedite dtype= kad god je prirodna širina manja:
sensor = np.array(samples, dtype=np.uint16)
Ponovno omatanje cjelobrojnog polja bez argumenta dtype= kopira i pretvara u float, što troši i vrijeme i RAM. Kad su performanse važne, imenujte dtype.
6.4.3. Dtype postojećeg polja#
dtype čita dtype polja kao cjelobrojni kod tipa koji polje interno nosi:
a = np.array([1, 2, 3], dtype=np.uint8)
print(a.dtype) # 66 (the integer value of ``'B'``)
Cjelobrojni kodovi tipa odgovaraju konstantama izloženima u modulu numpy – numpy.uint8, numpy.int8, numpy.uint16, numpy.int16, numpy.float, numpy.bool – pa je usporedba dtypea s konstantom modula način na koji skripta grana ovisno o tome što polje sadrži:
if a.dtype == np.uint8:
... # uint8 branch
6.4.4. Pravila povišenja tipa#
Dva polja različitih dtypeova mogu biti operandi istog operatora. numpy bira tip rezultata prema kratkoj tablici:
lijevo | desno | rezultat |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bilo koji |
|
|
Redak uint16 / int16 povisuje se izravno na float jer numpy na kameri nema 32-bitni cjelobrojni dtype.
Kada binarni operator ima Python skalar na jednoj strani, skalar se pretvara u jednoelementno polje najmanjeg prikladnog dtypea: 123 postaje uint8 polje, -1000 postaje int16, a Python float postaje float.
6.4.5. Cjelobrojno prelijevanje se omata#
Operacije nad dva polja istog cjelobrojnog dtypea zadržavaju taj dtype, čak i kada se rezultat prelije. Prijenos se tiho odbacuje:
a = np.array([200, 200], dtype=np.uint8)
b = np.array([100, 100], dtype=np.uint8)
print(a + b)
Izlaz:
array([44, 44], dtype=uint8)
Rezultat je 300 mod 256 == 44. Kada međurezultat treba veći raspon nego što ulazni dtype dopušta, prvo pretvorite tip:
c = np.array(a, dtype=np.uint16) + b
# array([300, 300], dtype=uint16)
Ovo pravilo vrijedi za svaki cjelobrojni operator – +, -, *, //, %, &, |, ^. Float polja se nikada ne prelijevaju (umjesto toga povisuju se u beskonačnost), pa je trik s pretvaranjem potreban samo u cjelobrojnom slučaju.