2011-10-10 14 views
7

Ho una matrice numpy grande di byte firmati (dtype int8). Contiene valori nell'intervallo intero da -128 a +127. Mi piacerebbe convertire l'efficiente in un array di byte senza segno (dtype uint8) aggiungendo 128 a ciascun elemento, in modo che -128 → 0, 0 → 128, +127 → 255, ecc. quindi, ovviamente, i risultati sono ancora inserirsi in un byte senza segno.Come posso trasformare in modo efficiente un array numpy.int8 in un array numpy.uint8 con valori spostati?

Aggiunta elementare semplice data il risultato numerico corretto, ma crea una matrice di risultati utilizzando il doppio della memoria (dtype int16) oltre all'array di origine, anche se sono necessari solo i byte bassi degli elementi del risultato.

>>> import numpy 
>>> a = numpy.array([-128, -1, 0, 1, 127 ], dtype=numpy.int8) 
>>> b = a + 128 
>>> b 
array([ 0, 127, 128, 129, 255], dtype=int16) 

C'è un modo per controllare la dtype dell'array risultato di essere uint8?

L'approccio alternativo di modificare i valori sul posto e "lanciare" i dati a un nuovo tipo, in questo modo:

>>> for i in xrange(0, 5): 
...  if a[i] < 0: 
...   a[i] -= 128 
...  elif a[i] >= 0: 
...   a[i] += 128 
... 
>>> a 
array([ 0, 127, -128, -127, -1], dtype=int8) 
>>> a.view(dtype=numpy.uint8) 
array([ 0, 127, 128, 129, 255], dtype=uint8) 

è molto più efficiente dello spazio ma molto costoso in tempo per grandi array con il trasformazione in Python.

Come posso eseguire questa trasformazione sul posto e rapidamente?

risposta

14
 
import numpy as np 
a = np.array([-128, -1, 0, 1, 127], dtype=np.int8) 
a = a.view(np.uint8) 
a += 128 
print a 
# -> array([ 0, 127, 128, 129, 255], dtype=uint8) 

Questo non crea copie e tutte le operazioni sono sul posto.

MODIFICA: più sicuro trasmettere prima a uint --- è definito wrap-around senza segno. EDIT2: s/numpy/np/g;

+0

Grazie. Non mi è venuto in mente di sfruttare il wrap non firmato combinato con l'operatore add-assign per avere un certo controllo sul tipo del risultato della somma. –

1
In [18]: a = numpy.array([-128, -1, 0, 1, 127 ], dtype=numpy.int8) 
In [19]: z = a.view(dtype=numpy.uint8) 

In [20]: z += 128 

In [21]: z 
Out[21]: array([ 0, 127, 128, 129, 255], dtype=uint8) 

Spero di non aver frainteso i requisiti.

Problemi correlati