Numpy:检查数组中的某个位是否设置为 1 或 0?
Numpy: check whether a bit is set to 1 or 0 in an array?
假设如下:
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
我相信答案可能非常简单,但 google 一点帮助也没有,而且 this related question is referring only to bytes.
由于我需要执行此操作数十亿次,我想知道是否有一种 pythonic 方法可以使其尽可能快地运行。
您可以使用 bin
将 python 中的数字转换为二进制字符串
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
你应该相应地调整值
您可以使用 [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”位的数量还是检查是否设置了特定位。
查一下,我想更简单的方法是:bool(n&(1<<b))
,其中n
是被测的数字,b
是位(从0开始)。
要计算“1”位的个数,我想没有什么比查找更快的了table。
例如,您可以使用 65k 内存并将 256 位分成 16 组,每组 16 位。然后,您在 table 中查找计数器的值。
为了生成 table,您可以使用任何其他提到的方法。例如:
table = [bin(i).count('1') for i in xrange(1<<16)]
然后,要计算位数,您可以将 table 中的值相加,例如:
n = 0x123456789123456789
cnt = 0
while n > 0:
cnt += table[n%((1<<16)-1)]
n >>= 16
如果你有足够的内存,你可以增加你的table。对于 32 位 table,您将需要 4GB 内存。这是处理与内存消耗的经典权衡。
假设如下:
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
我相信答案可能非常简单,但 google 一点帮助也没有,而且 this related question is referring only to bytes.
由于我需要执行此操作数十亿次,我想知道是否有一种 pythonic 方法可以使其尽可能快地运行。
您可以使用 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
你应该相应地调整值
您可以使用 [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”位的数量还是检查是否设置了特定位。
查一下,我想更简单的方法是:bool(n&(1<<b))
,其中n
是被测的数字,b
是位(从0开始)。
要计算“1”位的个数,我想没有什么比查找更快的了table。 例如,您可以使用 65k 内存并将 256 位分成 16 组,每组 16 位。然后,您在 table 中查找计数器的值。
为了生成 table,您可以使用任何其他提到的方法。例如:
table = [bin(i).count('1') for i in xrange(1<<16)]
然后,要计算位数,您可以将 table 中的值相加,例如:
n = 0x123456789123456789
cnt = 0
while n > 0:
cnt += table[n%((1<<16)-1)]
n >>= 16
如果你有足够的内存,你可以增加你的table。对于 32 位 table,您将需要 4GB 内存。这是处理与内存消耗的经典权衡。