通过同时筛选 Pandas 联接来加快数据帧处理速度



>我有两个数据帧,一个很大,另一个非常大。

df1: "classid"(text), "c1" (numeric), "c2"(numeric)
df2: "classid"(text), "c3" (numeric), "c4"(numeric)

我想根据 df2 上的值过滤 df1。在伪代码中,人们会这样表述它:

df2[(df2.classid == df1.classid) & (df2.c3 < df1.c1) & (df2.c4 < df1.c2)]

现在,我通过在 df1 中迭代行并在 df2(一个 3mil 行表)上进行一些 40k 过滤器调用来做到这一点。显然它的工作太慢了。

df = dataframe()
for row in df1:
    dft = df2[(df2.classid == row.classid) & (df2.c3 < row.c1) & (df2.c4 < row.c2)]
    df.add(dft)

我想最好的选择是进行内部连接,然后进行(df2.c3 <df1.c1)和(df2.c4><df1.c2)过滤,但问题是内部连接会创建一个巨大的表,因为classid不是索引,也不是唯一的行标识符。如果可以同时应用过滤,那可能会起作用。有什么想法吗?>

迭代

应该是最后的手段,我会将其他 dfs 列 c1 和 c2 合并到 df:

df = df.merge(df1, on='classid', how='left')
然后

,我将按classid分组,然后过滤行,如以下示例所示:

In [95]:
df = pd.DataFrame({'classid':[0,0,1,1,1,2,2], 'c1':np.arange(7), 'c2':np.arange(7), 'c3':3, 'c4':4})
df
Out[95]:
   c1  c2  c3  c4  classid
0   0   0   3   4        0
1   1   1   3   4        0
2   2   2   3   4        1
3   3   3   3   4        1
4   4   4   3   4        1
5   5   5   3   4        2
6   6   6   3   4        2
In [100]:
df.groupby('classid').filter(lambda x: len( x[x['c3'] < x['c1']] & x[x['c4'] < x['c2']]  ) > 0)
Out[100]:
   c1  c2  c3  c4  classid
2   2   2   3   4        1
3   3   3   3   4        1
4   4   4   3   4        1
5   5   5   3   4        2
6   6   6   3   4        2