Numpy:检查数组中的某个位是设置为1还是0?

时间:2015-02-06 12:37:44

标签: python numpy bit-manipulation bit bitstring

假设以下内容:

bitstring = numpy.random.random_integers(0,2**32,size=8).astype(numpy.uint32)

如何找出256位中的哪一位设置为1?我有这个...但这很疯狂,不是吗?

maximum = (2**32)-1
for checkbit in range (256):
    yes = bool(numpy.bitwise_and((2**checkbit)%maximum, bitstring[  (  (checkbit // maximum) + checkbit % maximum ) // 32  ] ) )
    print 'bit', checkbit, 'set to', yes, 'in string', (  (checkbit // maximum) + checkbit % maximum ) // 32

我相信答案可能非常简单,但谷歌根本没有帮助,this related question is referring only to bytes

由于我需要这么做几十亿次,我想知道是否有一种pythonic方式让它尽可能快地工作。

3 个答案:

答案 0 :(得分:3)

您可以使用[np.unpackbits] 1,但首先必须将您的数组视为np.uint8,并注意自己如何计算系统的结尾对结果的影响你得到:

>>> np.unpackbits(bitstring.view(np.uint8))
array([1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1,
       1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0,
       0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1,
       1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0,
       1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
       1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0,
       1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1,
       0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1,
       1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0,
       0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0,
       0, 0, 0], dtype=uint8)

答案 1 :(得分:3)

我不确定你是否要计算" 1"位或检查特定位是否已设置。

要检查,我想更简单的方法是:bool(n&(1<<b)),其中n是要测试的数字,b是位(从0开始)。

计算&#34; 1&#34;我觉得没有比查询表更快的了。 例如,您可以使用65k的内存并将256位分成16组16位。然后,在表格中查找计数器的值。

为了生成表,您可以使用任何其他提到的方法。例如:

table = [bin(i).count('1') for i in xrange(1<<16)]

然后,要计算位数,您只需将表中的值相加,例如:

n = 0x123456789123456789
cnt = 0
while n > 0:
    cnt += table[n%((1<<16)-1)]
    n >>= 16

如果你有足够的内存,你可以增加你的表。对于32位表,您将需要4GB内存。这是处理与内存消耗的经典权衡。

答案 2 :(得分:1)

您可以将python中的数字转换为bin

的二进制字符串
n = 4187390046
binary_str = bin(n)

哪个收益

Out[7]: '0b11111001100101101000000001011110'

然后你可以在该字符串中找到1的所有索引,例如

def find_ones(s):
    return [i - 2 for i, bit in enumerate(s) if bit == '1']

由于二进制字符串具有前导0b,因此您应相应地调整值