将pandas groupby的结果应用于多行



我有一个数据框df,看起来像这样:

PO  SO        Date  Name  Qty
0  123  34  2020-01-05  Carl    5
1  111  55  2020-10-10  Beth    7
2  123  12  2020-02-03  Greg   11
3  101  55  2019-12-03  Carl    3
4  123  34  2020-11-30  Beth   24
5  111  55  2019-04-02  Greg    6
6  202  99  2020-05-06  Beth   19

我想做的是用POSO分组时数据帧的最小日期替换日期。例如,有两行PO为"123",SO为"34"。由于这些行中Date的最小值是'2020-01-05',所以这两行都应该将它们的Date列设置为'2020-01-05'。

因此结果看起来像这样:

PO  SO        Date  Name  Qty
0  123  34  2020-01-05  Carl    5
1  111  55  2019-04-02  Beth    7
2  123  12  2020-02-03  Greg   11
3  101  55  2019-12-03  Carl    3
4  123  34  2020-01-05  Beth   24
5  111  55  2019-04-02  Greg    6
6  202  99  2020-05-06  Beth   19

您可以使用transformgroupby来创建"计算列",这样您就可以避免混乱的merge:

df = pd.DataFrame({'PO':  [123, 111, 123, 101, 123, 111, 202], 
'SO':   [34, 55, 12, 55, 34, 55, 99], 
'Date': ['2020-01-05', '2020-10-10', '2020-02-03', '2019-12-03', '2020-11-30', '2019-04-02', '2020-05-06'], 
'Name': ['Carl', 'Beth', 'Greg', 'Carl', 'Beth', 'Greg', 'Beth'], 
'Qty':  [5, 7, 11, 3, 24, 6, 19]})
df_grouped = df.copy()
df_grouped['Date'] = df_grouped.groupby(['PO', 'SO'])['Date'].transform('min')
df_grouped
Out[1]: 
PO  SO        Date  Name  Qty
0  123  34  2020-01-05  Carl    5
1  111  55  2019-04-02  Beth    7
2  123  12  2020-02-03  Greg   11
3  101  55  2019-12-03  Carl    3
4  123  34  2020-01-05  Beth   24
5  111  55  2019-04-02  Greg    6
6  202  99  2020-05-06  Beth   19

为了完成这一点,我们将使用POSOPOSO的每个组合的最小Date来创建一个密钥。我们使用groupbymin来完成这个任务。

import pandas as pd
df = pd.DataFrame({'PO':  [123, 111, 123, 101, 123, 111, 202], 
'SO':   [34, 55, 12, 55, 34, 55, 99], 
'Date': ['2020-01-05', '2020-10-10', '2020-02-03', '2019-12-03', '2020-11-30', '2019-04-02', '2020-05-06'], 
'Name': ['Carl', 'Beth', 'Greg', 'Carl', 'Beth', 'Greg', 'Beth'], 
'Qty':  [5, 7, 11, 3, 24, 6, 19]})
df_grouped = df[['PO', 'SO', 'Date']].groupby(by=['PO', 'SO'], as_index=False, dropna=False).min()
print(df_grouped)
PO  SO        Date
0  101  55  2019-12-03
1  111  55  2019-04-02
2  123  12  2020-02-03
3  123  34  2020-01-05
4  202  99  2020-05-06

现在我们可以将它与原始数据框合并,将旧的Date列替换为df_grouped中的Date列。

df = pd.merge(df.drop(columns=['Date']), df_grouped, on=['PO', 'SO']) 
df = df[['PO', 'SO', 'Date', 'Name', 'Qty']] # reset column order
print(df)
PO  SO        Date  Name  Qty
0  123  34  2020-01-05  Carl    5
1  123  34  2020-01-05  Beth   24
2  111  55  2019-04-02  Beth    7
3  111  55  2019-04-02  Greg    6
4  123  12  2020-02-03  Greg   11
5  101  55  2019-12-03  Carl    3
6  202  99  2020-05-06  Beth   19

相关内容

最新更新