我有一个大的Pandas数据帧(大多数用途的Numpy ndarray
的子类),包含二进制字符串(0和1)。我需要找到这些字符串中所有零的位置,然后标记它们。此外,我预计零的位置相对稀疏(约占所有位位置的1%)。
基本上,我想运行这样的东西:
import pandas as pd
x = pd.Series([ '11101110', '11111101' ], ) # start with strings
x = pd.Series([ 0b11101110, 0b11111101 ], ) # ... or integers of a known bit length
zero_positions = find_zero_positions( x )
屈服zero_positions =
......
value
row bit
0 4 0
0 0
1 1 0
我已经尝试了几种不同的方法来做到这一点,但没有提出任何比一次循环一行更好的方法。 (编辑:我想看的实际字符串比这里的8位示例长得多,所以查找表不起作用。)
我不确定将此作为字符串问题(Pandas的Vectorized string methods不提供子字符串位置查找方法)或数字问题(使用类似{{ 3}},也许?)。
答案 0 :(得分:2)
您可以使用numpy.unpackbits
,如下所示,从此表单的ndarray开始:
In [1]: x = np.array([[0b11101110], [0b11111101]], dtype=np.uint8)
In [2]: x
Out[2]:
array([[238],
[253]], dtype=uint8)
In [3]: df = pd.DataFrame(np.unpackbits(x, axis=1))
In [4]: df.columns = df.columns[::-1]
In [5]: df
Out[5]:
7 6 5 4 3 2 1 0
0 1 1 1 0 1 1 1 0
1 1 1 1 1 1 1 0 1
然后从DataFrame中,只需stack
并找到零:
In [6]: s = df.stack()
In [7]: s.index.names = ['row', 'bit']
In [8]: s[s == 0]
Out[8]:
row bit
0 4 0
0 0
1 1 0
dtype: uint8
我认为这是一种相当有效的方法。
答案 1 :(得分:1)
一个好的解决方案是将输入分成小块并在备忘录查找表中使用它(在第一次计算时)。
,例如,如果每个数字/数组是128位;将其分成八个16位的部分,这些部分在表格中查找。在最坏的情况下,查找表需要2个 16 ~65536个条目 - 但是如果零非常稀疏(例如,在任何8个比特组中最多只有两个零,则仅需要约64个)。根据稀疏程度的不同,你可以增加大块的大小。
答案 2 :(得分:1)
在“yuck”部门,我想进入以下选手:
def numpyToBinString(numpyValue):
return "".join( [str((numpyValue[0] >> shiftLength) & 1 ) for shiftLength in range(numpyValue.dtype.itemsize * 8)] )
适用于shape(,)ndArrays,但可以使用@vectorize装饰器进行扩展。
答案 3 :(得分:0)
您可以使用查找表。
创建一个表,对于0-255中的每个数字都有0个位置,并且有一个访问它的函数,称之为zeroBitPositions
,这将返回一个列表。
然后,假设您将数字存储为python long类型(我相信它具有无限精度)。您可以执行以下操作:
allZeroPositions = []
shift = 0
while (num >> shift) > 0:
zeroPositions += [x + shift for x in zeroBitPositions ((num >> shift) & 0xFF)]
shift += 8
希望这是一个好的开始。