我有几千个比特串作为long存储。每个位串是1024位。我想创建一个数组,每个位的比率是1。
例如(伪代码):
bs = [
1 0 0 0,
0 1 1 0,
1 1 0 0,
0 0 0 0
]
ratios(bs) => [0.5, 0.5, 0.25 0.0]
我现在的慢码是:
def mean_signature(bitstrings, bit_count):
means = []
for b in range(bit_count):
m = sum((x >> b) & 1 for x in bitstrings) / len(bitstrings)
means.append(m)
return means
我将要修改代码,这样外部循环就结束了,但是我想我一定遗漏了一些东西可能是用numpy位数组。
最佳答案
有一种方法可以做到,但它可能不是最有效的方法。
在演示中,我将使用8位整数,但它也可以用于1024位整数。
In [28]: bs = [0b11110000, 0b11111100, 0b11000000, 0b11111110, 0b00001100]
In [29]: bs
Out[29]: [240, 252, 192, 254, 12]
In [30]: nbits = 8
In [31]: bits = np.array([list(np.binary_repr(b, width=nbits)) for b in bs], dtype=np.uint8)
In [32]: bits
Out[32]:
array([[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 0, 0],
[1, 1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 1, 1, 0, 0]], dtype=uint8)
bits
是包含每个值二进制表示的位的数组所需的比率是列的平均值:In [33]: bits.mean(axis=0)
Out[33]: array([ 0.8, 0.8, 0.6, 0.6, 0.6, 0.6, 0.2, 0. ])
这些值的顺序是从最高位到最低位结果的索引与通常的位索引匹配可能更自然。为此,只需颠倒结果:
In [34]: bits.mean(axis=0)[::-1]
Out[34]: array([ 0. , 0.2, 0.6, 0.6, 0.6, 0.6, 0.8, 0.8])