2

ndarray我有一个包含二进制字符串(0 和 1)的大型 Pandas 数据框(大多数用途的 Numpy 子类)。我需要找到这些字符串中所有零的位置,然后标记它们。此外,我希望零的位置相对稀疏(约占所有位位置的 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 的向量化字符串方法不提供子字符串位置查找方法)或数字问题(使用类似的东西numpy.unpackbits,也许?)会更有效。

4

4 回答 4

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

我认为这将是一种相当有效的方法。

于 2013-06-11T00:35:02.123 回答
1

一个好的解决方案是将输入分成小块,并在记忆查找表中使用它(您第一次计算的地方)。

例如,如果每个数字/数组是 128 位;将其分解为八个 16 位的部分,在表格中查找。在最坏的情况下,查找表需要 2个 16 ~ 65536 个条目——但如果零非常稀疏(例如,任何 8 位组中最多两个零只需要约 64 个)。根据稀疏程度,您可以增加块的大小。

于 2013-06-11T00:07:19.617 回答
1

在“恶心”部门,我想输入以下参赛者:

def numpyToBinString(numpyValue):
    return "".join( [str((numpyValue[0] >> shiftLength) & 1 ) for shiftLength in range(numpyValue.dtype.itemsize * 8)] )

适用于 shape (,) ndArrays,但可以使用 @vectorize 装饰器进行扩展。

于 2013-09-29T23:00:38.747 回答
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

希望这是一个好的开始。

于 2013-06-11T00:10:42.507 回答