Python 将int16 numpy阵列扩展为int8 numpy阵列的有效方法是什么

Python 将int16 numpy阵列扩展为int8 numpy阵列的有效方法是什么,python,numpy,casting,Python,Numpy,Casting,我试图找到一种有效的方法,使用特定的缩放函数将2字节(-32K->+32K)numpy int数组缩放到8位(0->255)。 最低效的方法是(其中minVal和maxVal是原始2字节numpy数组中的最小值和最大值,原始数组中的paddingVal将设置为0): 我不知道如何避免循环,仍然做如果。。。并应用缩放函数 thx试试: byte_array[i] = (((val << 16) >> 8) & 0xFF0000) >> 16 byte_

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

我不知道如何避免循环,仍然做如果。。。并应用缩放函数

thx

试试:

byte_array[i] = (((val << 16) >> 8) & 0xFF0000) >> 16
byte_数组[i]=((val>8)和0xFF0000)>>16

它假设val是0到65535之间的32位整数,您可以使用掩码从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 = np.round(255.0 * (pixel_array - minVal) / (maxVal - minVal - 1.0)).astype(np.uint8)
byte_array[pixel_array == paddingVal] = 0

编辑:正如Joe Kington在对问题的评论中指出的那样,这是以内存换取速度。

val在本例中是一个负符号16位int,因此上面的方法无法解决问题。在任何情况下,性能与原来的性能都没有根本的不同。我认为,无论如何,必须摆脱显式循环。@thefog您可以在中转换32位将
-32768
32767
之间的整数转换为32位整数,该整数将在
0
65535
之间,使用
(int+0x10000)和0xFFFEFFFF
。这意味着在缩放
-1
后(因为它在2的补码中的位是满的)变成
255
等等。@它避免了浮点运算、乘法和对舍入的调用。我想如果代码执行相同的操作,代码不会运行得太接近硬件:PJust仅供参考:绝对不需要循环。如果内存不紧,只需执行
字节数组=(255.0*(pixel_array-minVal)/(maxVal-minVal-1.0)).astype(np.uint8)
。之后可以使用
字节数组[pixel_array==paddingVal]设置“padding”值=0
。虽然内存效率不高,但速度会比您当前所做的快得多。好吧,这肯定快得多。很好,python是多么紧凑。正如前面警告您的那样,我在注释中发布的版本隐式地占用了值的底部,而不是四舍五入。如果您不介意的话,它比调用快一点ing
numpy.round
,但它与您的原始代码不同(@jorgeca的答案应该会给出与您的原始解决方案相同的结果)。由于出现错误,因此失败了。我尝试了类似的方法,得到了:byte_array[~mask]=round(255.0*(pixel_array[~mask]-minVal)/(maxVal-minVal-1.0))TypeError:只有长度为1的数组才能转换为Python标量对不起,
round
是一个内置的Python,只适用于标量。我会解决这个问题。
byte_array = np.round(255.0 * (pixel_array - minVal) / (maxVal - minVal - 1.0)).astype(np.uint8)
byte_array[pixel_array == paddingVal] = 0