在ndarray中获取过滤数据检查子字符串值的最快方法

时间:2016-08-25 11:42:29

标签: numpy

我有大量数据:

>>> len(b)
6636849
>>> print(b)
[['60D19E9E-4E2C-11E2-AA9A-52540027E502' '100015361']
 ['60D19EB6-4E2C-11E2-AA9A-52540027E502' '100015385']
 ['60D19ECE-4E2C-11E2-AA9A-52540027E502' '100015409']
 ..., 
 ['8CC90633-447E-11E6-B010-005056A76B49' '106636785']
 ['F8C74244-447E-11E6-B010-005056A76B49' '106636809']
 ['F8C7425C-447E-11E6-B010-005056A76B49' '106636833']]

我需要获取过滤后的数据集,即字符串中包含(或以“106”开头)的所有内容。类似下面的代码使用子字符串操作而不是数学运算:

>>> len(b[b[:,1] > '10660600'])
30850

3 个答案:

答案 0 :(得分:1)

我认为numpy不适合这种类型的操作。你可以简单地使用基本的python操作。这是一些示例数据a

import random # for the test data
a = []
for i in range(10000):
    a.append(["".join(random.sample('abcdefg',3)), "".join(random.sample('01234567890',8))])

answer = [i for i in a if i[1].find('106') != -1]

请注意,startswithfind快得多,因为find必须在所有位置查找匹配的子字符串。

为什么你需要首先使用如此庞大的列表/数组来解决这个问题并不太清楚,并且当首先不在列表中包含这些值时,可能会有更好的解决方案。

答案 1 :(得分:1)

这是一个简单的熊猫解决方案

import pandas as pd

df = pd.DataFrame(b, columns=['1st String', '2nd String'])
df_filtered = df[df['2nd String'].str.contains('106')]

这会给你

In [29]: df_filtered
Out[29]: 
                             1st String 2nd String
3  8CC90633-447E-11E6-B010-005056A76B49  106636785
4  F8C74244-447E-11E6-B010-005056A76B49  106636809
5  F8C7425C-447E-11E6-B010-005056A76B49  106636833

更新:时间安排结果

使用Benjamin的列表a作为测试样本:

In [20]: %timeit [i for i in a if i[1].find('106') != -1]
100 loops, best of 3: 2.2 ms per loop

In [21]: %timeit df[df['2nd String'].str.contains('106')]
100 loops, best of 3: 5.94 ms per loop

所以看起来Benjamin的答案实际上要快3倍。这让我感到惊讶,因为我的印象是the operation in pandas is vectorized。此外,当a长100倍时,速度比不会改变。

答案 2 :(得分:0)

查看np.char子模块中的函数:

data = [['60D19E9E-4E2C-11E2-AA9A-52540027E502', '100015361'],
 ['60D19EB6-4E2C-11E2-AA9A-52540027E502', '100015385'],
 ['60D19ECE-4E2C-11E2-AA9A-52540027E502', '100015409'],
 ['8CC90633-447E-11E6-B010-005056A76B49', '106636785'],
 ['F8C74244-447E-11E6-B010-005056A76B49', '106636809'],
 ['F8C7425C-447E-11E6-B010-005056A76B49', '106636833']]
data = np.array([r[1] for r in data], np.str)
idx = np.char.startswith(data,  '106')
print(idx)