熊猫比较并求和两个大小不同的DataFrame之间的值

时间:2020-10-19 05:03:17

标签: python pandas dataframe

假设我有两个大小不同的数据框:

df1 = pd.DataFrame(dict(xlow=np.linspace(0, 10, 11), 
                           xup=np.linspace(1.0, 11, 11))) 
df2 = pd.DataFrame(dict(x=np.random.uniform(low=1, high=10, size=(20,)), 
                           volume=np.random.randint(0, 10, size=20)))
我拥有的

df1: 
    xlow   xup
0    0.0   1.0
1    1.0   2.0
2    2.0   3.0
3    3.0   4.0
4    4.0   5.0
5    5.0   6.0
6    6.0   7.0
7    7.0   8.0
8    8.0   9.0
9    9.0  10.0
10  10.0  11.0

和:

df2:
         x  volume
0   1.632789       8
1   8.346898       7
2   1.372285       2
3   1.946896       9
4   7.047305       0
5   3.851938       4
6   2.439664       7
7   8.823509       1
8   1.136700       1
9   8.766352       8
10  2.135441       8
11  8.092385       4
12  6.532898       3
13  7.199914       2
14  1.036684       0
15  9.714326       1
16  5.964111       0
17  9.625200       2
18  9.999818       6
19  9.891857       1

现在,我想在df1中添加第三列,例如total_volume,它是位于xlow和df1的xup单行之间的体积的总和。我可以使用:

df1['total_volume']=df1.apply(lambda row: df2[(df2.x<=row['xup']) & (df2.x>row['xlow'])].volume.sum(),axis=1)

which results in 

    xlow   xup  total_volume
0    0.0   1.0             0
1    1.0   2.0            20
2    2.0   3.0            15
3    3.0   4.0             4
4    4.0   5.0             0
5    5.0   6.0             0
6    6.0   7.0             3
7    7.0   8.0             2
8    8.0   9.0            20
9    9.0  10.0            10
10  10.0  11.0             0

我们可以将第二行的值检查为:

df2[(df2.x<=2) & (df2.x>1) ].volume.sum()=20

实际上,我的df1最多可以有数十万行,因此最多可能需要数十分钟才能完成。有没有更多的vectorize / pythonic方法来做到这一点。我尝试将熊猫合并并加入,但没有成功,很可能是因为我仍然是新手。

谢谢您的帮助!

2 个答案:

答案 0 :(得分:0)

df1的每一行都具有相同的范围吗? 然后迭代df2并简单地添加到df1。

for d in df2:
    df1[d.x//1].total_volume += d.volume

如果没有,请排序df2。

答案 1 :(得分:0)

如果垃圾箱不重叠,可以将cut与聚合sum一起使用,然后按DataFrame.join添加到df1

df2['g'] = pd.cut(df2['x'], bins=[0] + df1['xup'].tolist(), labels=df1['xup'])

df2 = df1.join(df2.groupby('g')['volume'].sum(), on='xup')
print (df2)

    xlow xup  volume
0    0.0   1       0
1    1.0   2      20
2    2.0   3      15
3    3.0   4       4
4    4.0   5       0
5    5.0   6       0
6    6.0   7       3
7    7.0   8       2
8    8.0   9      20
9    9.0  10      10
10  10.0  11       0