按ID分组数据框后执行操作

时间:2019-09-12 00:33:49

标签: python-3.x pandas pandas-groupby

我当前的数据框:

df=
[id,date,       session_rank,sales]
[1, 06-01-2018, 5,             10 ]
[1, 08-01-2018, 6,             30 ]
[2, 06-01-2018, 1,              0 ]
[3, 05-01-2018, 3,             30 ]

我希望通过id进行汇总,以便最终通过以下方式为每个id分配1行:

df_new=
[id,total_days,total_sessions,total_sales]
[1,  3,         2,             40        ]
[2,  1,         1,             0         ]
[3,  1,         3,             30        ]

计算:

  每个ID的

days = max(date)-min(date)。   日期包括在内,因此08-01-2018-06-01-2018 =3。此外,如果仅为用户提供1个日期或会话,则只需填写1。

     

sessions =每个ID的最大(session_rank)-min(session_rank)

     

sales =每个ID的总和(sales)

希望有人可以提供帮助!

2 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点。我的想法是对日期进行分组,然后执行自定义汇总。注意:我正在重建您的df,并在date上使用转换器来获取datetime dtype。

import pandas as pd
import io

s = '''id  date  session_rank  sales
       1  06-01-2018  5             10 
       1  08-01-2018  6             30 
       2  06-01-2018  1              0 
       3  05-01-2018  3             30'''

df = pd.read_csv(io.StringIO(s), sep='\s+', converters={'date': lambda x: pd.to_datetime(x, format='%d-%m-%Y')})
df = df.groupby('id').agg({'date': lambda x: ((x.max()-x.min()) + '1D').days,
                           'session_rank': lambda x: x if len(x)<2 else x.max()-x.min(),
                           'sales': sum})

print(df)

    date  session_rank  sales
id                           
1      3             1     40
2      1             1      0
3      1             3     30

答案 1 :(得分:0)

df.groupby('id').agg({
    'session_rank': lambda x:x if len(x)<2 else x.max()-x.min(),
    'sales': lambda y: y.sum(),
    'date': lambda z: ((z.max()-z.min()) + '1D').days})