Pandas - 有效地从列表中搜索数据框的列
Pandas - Searching Column of Data Frame from List Efficiently
我试图找出最有效的方法来搜索 Pandas 中的数据框,其中包含其他值的列表(数据框),而无需使用蛮力方法。有没有办法对其进行矢量化?我知道我可以 for 循环列表(或数据帧)的每个元素并使用 loc 方法提取数据,但我希望更快。我有一个包含 100 万行的数据框,我需要在其中搜索以提取 600,000 行的索引。
示例:
import pandas as pd
import numpy as np
df = pd.DataFrame({'WholeList': np.round(1000000*(np.random.rand(1000000)),0)})
df2 = pd.DataFrame({'ThingsToFind': np.arange(50000)+50000})
df.loc[1:10,:]
#Edited, now that I think about it, the 'arange' method would have been better to populate the arrays.
我想要最有效的方法来获取 df2 在 df 中的索引,它存在于 df 中。
谢谢!
Pandas 数据帧有一个非常有效的 isin()
方法:
df[df.WholeList.isin(df2.ThingsToFind)]
它在我的 MBP 上表现得相当不错:
CPU times: user 3 µs, sys: 5 µs, total: 8 µs
Wall time: 11 µs
我同意@JDLong - IMO Pandas 相当快:
In [49]: %timeit df[df.WholeList.isin(df2.ThingsToFind)]
1 loop, best of 3: 819 ms per loop
In [50]: %timeit df.loc[df.WholeList.isin(df2.ThingsToFind)]
1 loop, best of 3: 814 ms per loop
In [51]: %timeit df.query("WholeList in @df2.ThingsToFind")
1 loop, best of 3: 837 ms per loop
这是 np.searchsorted
的一种方法,因为看起来第二个数据框的元素已排序且唯一 -
def find_index(a,b, invalid_specifier = -1):
idx = np.searchsorted(b,a)
idx[idx==b.size] = 0
idx[b[idx] != a] = invalid_specifier
return idx
def process_dfs(df, df2):
a = df.WholeList.values.ravel()
b = df2.ThingsToFind.values.ravel()
return find_index(a,b, invalid_specifier=-1)
数组上的示例 运行 -
In [200]: a
Out[200]: array([ 3, 5, 8, 4, 3, 2, 5, 2, 12, 6, 3, 7])
In [201]: b
Out[201]: array([2, 3, 5, 6, 7, 8, 9])
In [202]: find_index(a,b, invalid_specifier=-1)
Out[202]: array([ 1, 2, 5, -1, 1, 0, 2, 0, -1, 3, 1, 4])
数据帧上的示例 运行 -
In [188]: df
Out[188]:
WholeList
0 3
1 5
2 8
3 4
4 3
5 2
6 5
7 2
8 12
9 6
10 3
11 7
In [189]: df2
Out[189]:
ThingsToFind
0 2
1 3
2 5
3 6
4 7
5 8
6 9
In [190]: process_dfs(df, df2)
Out[190]: array([ 1, 2, 5, -1, 1, 0, 2, 0, -1, 3, 1, 4])
我试图找出最有效的方法来搜索 Pandas 中的数据框,其中包含其他值的列表(数据框),而无需使用蛮力方法。有没有办法对其进行矢量化?我知道我可以 for 循环列表(或数据帧)的每个元素并使用 loc 方法提取数据,但我希望更快。我有一个包含 100 万行的数据框,我需要在其中搜索以提取 600,000 行的索引。
示例:
import pandas as pd
import numpy as np
df = pd.DataFrame({'WholeList': np.round(1000000*(np.random.rand(1000000)),0)})
df2 = pd.DataFrame({'ThingsToFind': np.arange(50000)+50000})
df.loc[1:10,:]
#Edited, now that I think about it, the 'arange' method would have been better to populate the arrays.
我想要最有效的方法来获取 df2 在 df 中的索引,它存在于 df 中。
谢谢!
Pandas 数据帧有一个非常有效的 isin()
方法:
df[df.WholeList.isin(df2.ThingsToFind)]
它在我的 MBP 上表现得相当不错:
CPU times: user 3 µs, sys: 5 µs, total: 8 µs
Wall time: 11 µs
我同意@JDLong - IMO Pandas 相当快:
In [49]: %timeit df[df.WholeList.isin(df2.ThingsToFind)]
1 loop, best of 3: 819 ms per loop
In [50]: %timeit df.loc[df.WholeList.isin(df2.ThingsToFind)]
1 loop, best of 3: 814 ms per loop
In [51]: %timeit df.query("WholeList in @df2.ThingsToFind")
1 loop, best of 3: 837 ms per loop
这是 np.searchsorted
的一种方法,因为看起来第二个数据框的元素已排序且唯一 -
def find_index(a,b, invalid_specifier = -1):
idx = np.searchsorted(b,a)
idx[idx==b.size] = 0
idx[b[idx] != a] = invalid_specifier
return idx
def process_dfs(df, df2):
a = df.WholeList.values.ravel()
b = df2.ThingsToFind.values.ravel()
return find_index(a,b, invalid_specifier=-1)
数组上的示例 运行 -
In [200]: a
Out[200]: array([ 3, 5, 8, 4, 3, 2, 5, 2, 12, 6, 3, 7])
In [201]: b
Out[201]: array([2, 3, 5, 6, 7, 8, 9])
In [202]: find_index(a,b, invalid_specifier=-1)
Out[202]: array([ 1, 2, 5, -1, 1, 0, 2, 0, -1, 3, 1, 4])
数据帧上的示例 运行 -
In [188]: df
Out[188]:
WholeList
0 3
1 5
2 8
3 4
4 3
5 2
6 5
7 2
8 12
9 6
10 3
11 7
In [189]: df2
Out[189]:
ThingsToFind
0 2
1 3
2 5
3 6
4 7
5 8
6 9
In [190]: process_dfs(df, df2)
Out[190]: array([ 1, 2, 5, -1, 1, 0, 2, 0, -1, 3, 1, 4])