簡體   English   中英

Pandas 列,其中每個值取決於另一個 df 查詢

[英]Pandas column where each value depends on another df query

我面臨着一個復雜的問題。 我有一個我有客戶的第一個數據框(請注意,ClientID 不是唯一的,您可以將相同的 ClientID 與不同的 TestDate 關聯):

df1:

ClientID  TestDate
1A        2019-12-24
1B        2019-08-26
1B        2020-01-12

我有另一個“操作”數據框,指示日期和涉及哪個客戶

df2:

LineNumber  ClientID  Date          Amount
1           1A        2020-01-12    50
2           1A        2019-09-24    15
3           1A        2019-12-25    20
4           1A        2018-12-30    30
5           1B        2018-12-30    60
6           1B        2019-12-12    40

我想要的是向 df1 添加一個包含平均數量和行數的列,但只采用 Date < TestDate 的 df2 行

例如,對於客戶端 1A,我將只取 LineNumber 2 和 4(因為第 1 行和第 3 行的日期晚於 TestDate),然后獲取 df1 的以下輸出:

預期 df1 :

ClientID  TestDate      NumberOp  MeanOp
1A        2019-12-24    2         22.5
1B        2019-08-26    1         60
1B        2020-01-12    2         50

注意:1B Client的第一行,由於TestDate是2019-08-26 ,所以只看到一個操作(LineNumber 6的操作是在2019-12-12做的,所以在2019-12-12之后,所以我不取了考慮在內)。

我已經有一個代碼可以做到這一點,但我必須在我的df1上使用iterrows ,這需要很iterrows

當前代碼(工作但很長):

for index, row in df1.iterrows():
    id = row['ClientID']
    date = row['TestDate']
    df2_known = df2.loc[df2['ClientID'] == id]
    df2_known = df2_known.loc[df2_known['Date'] < date]
    df1.loc[index, 'NumberOp'] = df2_known.shape[0]
    df1.loc[index, 'MeanOp'] = df2_known['Amount'].mean()

我有使用聚合的想法,以及meancount類的命令,但我必須按日期過濾每一行的事實是一個我無法弄清楚的大問題。 非常感謝您的幫助。

編輯:剩余問題:

答案編輯中給出的修復(“如果您想保留 df2 缺少的匹配鍵”)與我的問題不符。

事實上,如果 df2 中沒有操作可用於計算均值和計數,我想避免丟失 df1 的等效行。 我會用一個例子告訴你這個問題:

df = df2.merge(df1, on=['ClientID'], how='right')
print(df[df['ClientID'] == '5C'])

Output :
ClientID  TestDate    Date          Amount
5C        2019-12-12  2020-01-12    50     

如果我按照答案中給出的方式進行groupbytransform ,我的輸出將不會有任何CliendID == '5C' ,因為Date < TestDateDate is null永遠不會發生,所以當我執行df = df[(df['Date']<df['TestDate']) | (df['Date'].isnull())]時該行丟失df = df[(df['Date']<df['TestDate']) | (df['Date'].isnull())] df = df[(df['Date']<df['TestDate']) | (df['Date'].isnull())] 我個人希望在我的最終輸出中有一行CliendID == '5C' ,看起來像這樣:

ClientID  TestDate      NumberOp  MeanOp
5C        2019-12-12    0         NaN

您可以合並和轉換:

df = df2.merge(df1, on=['ClientID'])
#filter based on condition
df = df[df['Date']<df['TestDate']]
#get the mean and count into new columns
df['MeanOp'] = df.groupby(['ClientID'])['Amount'].transform('mean')
df['NumberOp'] = df.groupby(['ClientID'])['Amount'].transform('count')
#drop duplicates and irrelevant columns
df = df.drop(['Amount','Date','LineNumber'],1).drop_duplicates()

輸出:

  ClientID    TestDate  MeanOp  NumberOp
1       1A  2019-12-24    22.5         2
4       1B  2019-08-26    70.0         1

編輯:如果您想保留df2缺少的匹配鍵:

df = df2.merge(df1, on=['ClientID'], how='right')
df = df[(df['Date']<df['TestDate']) | (df['Date'].isnull())]
df['MeanOp'] = df.groupby(['ClientID'])['Amount'].transform('mean')
df['NumberOp'] = df.groupby(['ClientID'])['Amount'].transform('count')
df = df.drop(['Amount','Date','LineNumber'],1).drop_duplicates()

例子:

df1:

  ClientID    TestDate
0       1A  2019-12-24
1       1B  2019-08-26
2       1C  2019-08-26

output:

  ClientID    TestDate  MeanOp  NumberOp
1       1A  2019-12-24    22.5         2
4       1B  2019-08-26    70.0         1
5       1C  2019-08-26     NaN         0

更新:根據對帖子的編輯,如果您想按(Client_ID, TestDate)對它們進行(Client_ID, TestDate)

df = df2.merge(df1, on=['ClientID'], how='right')
df = df[(df['Date']<df['TestDate']) | (df['Date'].isnull())]
df['MeanOp'] = df.groupby(['ClientID','TestDate'])['Amount'].transform('mean')
df['NumberOp'] = df.groupby(['ClientID','TestDate'])['Amount'].transform('count')
df = df.drop(['Amount','Date','LineNumber'],1).drop_duplicates()

輸出:

df1
  ClientID    TestDate
0       1A  2019-12-24
1       1B  2019-08-26
2       1B  2020-01-12
3       1C  2019-08-26

df2
   LineNumber ClientID        Date  Amount
0           1       1A  2020-01-12      50
1           2       1A  2019-09-24      15
2           3       1A  2019-12-25      20
3           4       1A  2018-12-30      30
4           5       1B  2018-12-30      60
5           6       1B  2019-12-12      40

df
  ClientID    TestDate  MeanOp  NumberOp
1       1A  2019-12-24    22.5         2
4       1B  2019-08-26    60.0         1
6       1B  2020-01-12    50.0         2
8       1C  2019-08-26     NaN         0

暫無
暫無

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

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