Python / numpy中的快速/内置位操作?

时间:2012-05-09 20:55:26

标签: python numpy bit-manipulation

我正在使用一个外部库,它输出一个数据类型为“> u2”的numpy数组(big-endian,无符号,2字节/ 16位)。在我的例子中,只有10位有效(输出来自实际输出 little-endian 的硬件设备)。例如:

65283是最大值,对应于直接python输出的bin(65283)=0b1111111100000011,如果是小端则对应00001111111111

我想将库中的0-65283输出范围映射到10位硬件功能有意义的范围0-1023。我该怎么做?

我尝试了以下内容:

>>>import numpy as np

>>>arr=np.array([65283, 6528, 652, 65, 6], dtype=">u2")
>>>print arr/64  # same as arr/2**6 and arr >> 6
[1020  102   10    1    0]
>>>print arr.byteswap()
[ 1023 32793 35842 16640  1536]

但这并没有给出理想的结果。我发现bin()函数以big-endian格式输出(在这个numpy数组的情况下),但省略了填充零。例如,65283表示所有16位,但bin(6528)=0b1100110000000(中间缺少3个零)。

要修复此问题(并返回一个10位的小端数字),我可以得到6528的二进制形式,在中间添加3个零,并进行字节交换。但是1)这是非常繁琐的(每个元素完成)和2)零填充是不一致的(例如652需要6个零)。

有没有内置的方法来做到这一点?看起来struct模块(w / pack和/或unpack)可能有所帮助,但现在它对我来说是希腊语。任何帮助将不胜感激!

修改

相信我找到了罪魁祸首。上面我的例子(从65238的摄像机/库中获取实际值并假设半自由的附加值,显然只删除了最右边的数字)不会发生!例如6528在最低有效字节(00011001**1**0000000)中需要1,并且永远不会发生(只有10位有效)。

进一步检查后,我的代码(arr.byteswap()具有合法值)中的简单arr有效。 e.g:

>>>arr=np.array([12288, 13312, 12800, 12032, 13312, 13824, 65283, 0, 7936], dtype=">u2")
>>>arr.byteswap()
array([  48,   52,   50,   47,   52,   54, 1023,    0,   31], dtype=uint16)

我从未在我的代码中尝试过,只是在这个例子中。对困惑感到抱歉。但希望它可以帮助其他人绊倒这个问题(特别是如果你使用Basler相机!),结果证明这是微不足道的我猜...

1 个答案:

答案 0 :(得分:0)

import struct
struct.pack('<H',val)

或者,更好的是:

>>> arr.byteswap().newbyteorder()
array([65283,  6528,   652,    65,     6], dtype=uint16)
>>> arr.byteswap().newbyteorder().tostring()
'\x03\xff\x80\x19\x8c\x02A\x00\x06\x00'

docs