>我有两个数据帧,一个很大,另一个非常大。
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