什么是将int16 numpy数组扩展为int8 numpy数组的有效方法

时间:2013-06-18 16:40:49

标签: python numpy casting

我试图找到一种有效的方法,使用特定的缩放功能将2字节(-32K - > + 32K)numpy int数组缩放到8位(0 - > 255)。 效率非常低效的方法是(其中minVal和maxVal是原始2字节numpy数组中的min和Max值,原始中的paddingVal将设置为0):

...

pixel_array = np.zeros( length, dtype=np.int16)
byte_array = np.zeros( length, dtype=np.uint8)

....

i = 0
for val in np.nditer(pixel_array):
    value = 0.0
    if val == paddingVal:
        byte_array[i] = 0
    else:
        value = 255.0 * ( val - minVal ) / (maxVal - minVal - 1.0)    
        byte_array[i] = (round(value))
    i += 1  

我无法弄清楚如何避免循环并仍然执行if ...并应用缩放功能。

THX

2 个答案:

答案 0 :(得分:3)

尝试:

byte_array[i] = (((val << 16) >> 8) & 0xFF0000) >> 16

假设val是0到65535之间的32位整数

答案 1 :(得分:2)

你可以使用一个掩码来受益于numpy的矢量化(隐式循环),这会更快:

mask = pixel_array == paddingVal
byte_array[mask] = 0
byte_array[~mask] = np.round(255.0 * (pixel_array[~mask] - minVal) / (maxVal - minVal - 1.0))

它也可以这样做,因为你不必事先创建byte_array,所以它更干净:

byte_array = np.round(255.0 * (pixel_array - minVal) / (maxVal - minVal - 1.0)).astype(np.uint8)
byte_array[pixel_array == paddingVal] = 0

编辑:正如Joe Kington对问题的评论所指出的那样,这种记忆的速度。