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.