簡體   English   中英

如何匹配兩個數據框並獲得以下結果?

[英]How can I match the two data frame and get the following result?

我有以下 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

  1. 將付款與項目匹配后,我們基本上有以下數據框:
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 盈余

類似地,對於 projectC (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)

函數有助於將 Cost 和 Amount 之間的差異附加回數據幀

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM