Numpy 在ndarray中通过检查子字符串值获得过滤数据的最快方法
我有大量的数据:Numpy 在ndarray中通过检查子字符串值获得过滤数据的最快方法,numpy,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-
>>> 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
我认为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]
请记住,startswith
将比find
快得多,因为find必须在所有位置查找匹配的子字符串
现在还不太清楚为什么需要在这么大的列表/数组中执行此操作,如果要在列表中不包含这些值,可能会有更好的解决方案。我认为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]
请记住,startswith
将比find
快得多,因为find必须在所有位置查找匹配的子字符串
现在还不太清楚为什么需要在这么大的列表/数组中执行此操作,如果要在列表中不包含这些值,可能会有更好的解决方案。这里有一个简单的解决方案
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
所以看起来本杰明的答案实际上快了3倍。这让我很惊讶,因为我的印象是。此外,当
a
长100倍时,速比不会改变。这里有一个简单的解决方案
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
所以看起来本杰明的答案实际上快了3倍。这让我很惊讶,因为我的印象是。此外,当
a
长100倍时,速比不会改变。查看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)
查看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)
你会考虑把第二列解析成整数吗?你会考虑把第二列解析成整数吗?真的是:LeN(b [np.char,StastSub(b[:],1),1001)])实际上我想创建我自己的多维立方体,具有良好的查询性能,只是为了好玩和更好的理解。类似于磁盘上的MOLAP引擎。也许我走错了方向,但这是我在这个领域的第一步。很酷,的确:len(b[np.char.startswith(b[:,1],“1001”))实际上我想创建自己的多维多维多维数据集,具有良好的查询性能,只是为了好玩和更好的理解。类似于磁盘上的MOLAP引擎。也许我走错了方向,但这是我在这个领域的第一步。谢谢,这是非常有用的。性能案例对我来说非常重要。谢谢,它提供了很多信息。绩效案例对我来说非常重要。