通过对pandas连接进行相应的过滤来加速数据帧处理

时间:2015-04-14 08:58:17

标签: python sql pandas

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

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不是索引而不是唯一的行标识符。如果可以同时应用过滤,那可能会起作用。有什么想法吗?

1 个答案:

答案 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