我有两个数据帧,一个很大,另一个很大。
df1: "classid"(text), "c1" (numeric), "c2"(numeric)
df2: "classid"(text), "c3" (numeric), "c4"(numeric)
我想根据df1上的值过滤df2。在伪代码中,人们可以这样形成它:
df2[(df2.classid == df1.classid) & (df2.c3 < df1.c1) & (df2.c4 < df1.c2)]
现在我通过在df1中迭代行并在df2上执行一些40k过滤器调用来执行此操作,df2是3mil行表。显然效果太慢了。
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&lt; df1.c1)&amp; (df2.c4&lt; df1.c2)过滤但问题是内连接会创建一个巨大的表,因为classid不是索引而不是唯一的行标识符。如果可以同时应用过滤,那可能会起作用。有什么想法吗?
答案 0 :(得分:0)
迭代应该是最后的手段,我将其他dfs列c1和c2合并到df:
df = df.merge(df1, on='classid', how='left')
然后我将groupid分组,然后过滤行,如下例所示:
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