2011-10-10 250 views
7

我有一個大的numpy數組的簽名字節(dtype int8)。它包含全部-128到+127的值。我想通過給每個元素添加128來有效地將其轉換爲無符號字節數組(dtype uint8),例如-128→0,0→128,+ 127→255,所以當然結果仍然是放入一個無符號字節。如何有效地將numpy.int8數組轉換爲值轉換的numpy.uint8數組?

給出了正確的數值結果的簡單元素添加,但是除了源數組外,還創建了使用兩倍內存(dtype int16)的結果數組,儘管只需要結果元素的低位字節。

>>> 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) 

有沒有辦法來控制結果數組的dtypeuint8

就地修改值和數據「鑄造」到一個新的類型,這樣的替代方法:

>>> 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) 

是更有效利用空間,但是非常昂貴的在時間上與所述大陣列Python中的轉換。

我該如何快速地進行這種轉換?

回答

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) 

這不創建副本,並且所有操作都在原地。

EDIT:更安全地先投射到uint ---定義了無符號環繞。 EDIT2:s/numpy/np/g;

+0

謝謝。我沒有想到利用無符號的環繞結合add-assign運算符來控制總和結果的類型。 –

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) 

我希望我沒有誤解要求。