我有以下 df_project:
df_project = pd.DataFrame({'Project':['A','B','C'],'Day':[1,5,10],'Cost':[100,200,300]})
Project Day Cost
A 1 100
B 5 200
C 10 300
我还有以下 df_ payment:
df_payment = pd.DataFrame({'Payment':['P1','P2','P3','P4','P5','P6'],'Day':[2,3,5,6,7,11],'Amount':[50,40,100,50,70,280]})
Payment Day Amount
P1 2 50
P2 3 40
P3 5 100
P4 6 50
P5 7 70
P6 11 280
我想要得到以下结果:
df_result = pd.DataFrame({'Project':['A','A','A','B','B','B','np.Nan','C','C'],'Payment':['P1','P2',np.nan,'P3','P4','P5','P5','P6',np.nan],'Amount':[50,40,10,100,50,50,20,280,20]})
Project Payment Amount
A P1 50.0
A P2 40.0
A NaN 10.0
B P3 100.0
B P4 50.0
B P5 50.0
NaN P5 20.0
C P6 280.0
C NaN 20.0
逻辑是: 1.付款必须与天数大于或等于的项目匹配
所以我们可以看到P1和P2匹配A,P3,P4,P5匹配B,P6匹配C
- 付款与项目匹配后 我们基本上有以下数据框:
Project Payment
A P1
A P2
B P3
B P4
B P5
C P6
然后我们还将 df_ payment['Amount'] 与 df_project['Cost'] 进行匹配
因此 (P1,50) 和 (P2,40) 与 A 匹配,但 A 的成本为 100,赤字为 10,因此付款设置为 NaN
然后对于项目 B,(P3,100)、(P4,50)、(P5,70) 的盈余为 20,因此该项目设置为 NaN 以获得额外的 20 盈余
同样,对于项目C(P6,280)有20的赤字,所以结果将是这样的:
Project Payment Amount
A P1 50.0
A P2 40.0
A NaN 10.0
B P3 100.0
B P4 50.0
B P5 50.0
NaN P5 20.0
C P6 280.0
C NaN 20.0
有什么办法可以做到这一点吗?
最佳答案
使用merge_asof在最近的日子合并
M = pd.merge_asof(df_payment,df_project,on='Day').drop('Day',axis=1)
函数有助于将成本和金额之间的差异附加回数据框
def attach_difference(df):
A = df.Amount.sum()
B = df.Cost.max()
C = df.shape[0]
D = df.Payment.iloc[-1]
df = df.reset_index(drop=True)
if A-B < 0:
df.loc[C]= {'Payment':np.nan,
'Amount':abs(A-B),
'Project':df.Project.unique()[0],
'Cost':np.nan}
elif A - B > 0 :
df.loc[C-1,'Amount'] = df.loc[C-1,'Amount'] - (A-B)
df.loc[C]= {'Payment':D,
'Amount':A-B,
'Project':np.nan,
'Cost':np.nan}
return df
运行列表理解并将函数通过管道传输到每个组
outcome = [group.pipe(attach_difference)
.drop('Cost',axis=1)
for name, group in M.groupby('Project')]
(pd.concat(outcome,ignore_index=True)
.reindex(['Project','Payment','Amount'],
axis=1)
)
Project Payment Amount
0 A P1 50
1 A P2 40
2 A NaN 10
3 B P3 100
4 B P4 50
5 B P5 50
6 NaN P5 20
7 C P6 280
8 C NaN 20
关于python - 如何匹配两个数据框并得到以下结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60331269/