如何高效地将numpy.int8数组原地转换为值偏移的numpy.uint8数组?
我有一个很大的numpy数组,里面存的是带符号的字节(dtype int8
)。这个数组的值范围是从-128到+127。我想把它高效地转换成一个无符号字节的数组(dtype uint8
),方法是给每个元素加上128,这样-128就变成0,0变成128,+127变成255,等等。这样转换后,结果仍然可以放进无符号字节里。
简单地逐个加上128可以得到正确的数字结果,但这样会生成一个结果数组,它的内存使用量是原数组的两倍(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)
有没有办法让结果数组的dtype
变成uint8
呢?
另一种方法是直接在原数组上修改值,然后把数据“转换”成新类型,像这样:
>>> 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)
这种方法在空间上更高效,但对于大数组来说,转换的时间成本很高。
我该如何快速且在原地完成这个转换呢?
2 个回答
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)
我希望我没有误解需求。
18
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)
这段代码不会创建任何副本,所有的操作都是在原地进行的。
补充说明: 首先转换为无符号整数(uint)会更安全,因为无符号整数的循环特性是有定义的。
补充说明2: 把“numpy”替换成“np”。