根据日期时间数据逐月汇总

时间:2019-07-17 16:52:44

标签: pandas pandas-groupby

我有一个交易数据,如下所示。这是3个月的数据。

Card_Number Card_type   Category    Amount  Date
0   1       PLATINUM    GROCERY      100    10-Jan-18
1   1       PLATINUM    HOTEL        2000   14-Jan-18
2   1       PLATINUM    GROCERY      500    17-Jan-18
3   1       PLATINUM    GROCERY      300    20-Jan-18
4   1       PLATINUM    RESTRAUNT    400    22-Jan-18
5   1       PLATINUM    HOTEL        500    5-Feb-18
6   1       PLATINUM    GROCERY      400    11-Feb-18
7   1       PLATINUM    RESTRAUNT    600    21-Feb-18
8   1       PLATINUM    GROCERY      800    17-Mar-18
9   1       PLATINUM    GROCERY      200    21-Mar-18
10  2       GOLD        GROCERY      1000   12-Jan-18
11  2       GOLD        HOTEL        3000   14-Jan-18
12  2       GOLD        RESTRAUNT    500    19-Jan-18
13  2       GOLD        GROCERY      300    20-Jan-18
14  2       GOLD        GROCERY      400    25-Jan-18
15  2       GOLD        HOTEL        1500   5-Feb-18
16  2       GOLD        GROCERY      400    11-Feb-18
17  2       GOLD        RESTRAUNT    600    21-Mar-18
18  2       GOLD        GROCERY      200    21-Mar-18
19  2       GOLD        HOTEL        700    25-Mar-18
20  3       SILVER      RESTRAUNT    1000   13-Jan-18
21  3       SILVER      HOTEL        1000   16-Jan-18
22  3       SILVER      GROCERY      500    18-Jan-18
23  3       SILVER      GROCERY      300    23-Jan-18
24  3       SILVER      GROCERY      400    28-Jan-18
25  3       SILVER      HOTEL        500    5-Feb-18
26  3       SILVER      GROCERY      400    11-Feb-18
27  3       SILVER      HOTEL        600    25-Mar-18
28  3       SILVER      GROCERY      200    29-Mar-18
29  3       SILVER      RESTRAUNT    700    30-Mar-18

我正在努力低于数据框。

  Card_No Card_Type  D   Jan_Sp Jan_N Feb_Sp Feb_N Mar_Sp  GR_T  RES_T 
    1     PLATINUM   70  3300   5     1500   3     1000    2300  100
    2     GOLD       72  5200   5     1900   2     1500    2300  1100
    3     SILVER .   76  2900   5     900    2     1500    1800  1700

D =从第一次交易到最后一次交易的天数。

Jan_Sp =一月总支出。

Feb_Sp = 2月的总支出。

Mar_Sp = 3月的总支出。

Jan_N = 1月的交易次数。

Feb_N = 2月的交易次数

GR_T =杂货总支出。

RES_T = RESTRAUNT的总支出。

我尝试了以下代码。我对熊猫很陌生。

q9['Date'] = pd.to_datetime(Card_Number['Date'])
q9 = q9.sort_values(['Card_Number', 'Date'])
q9['D'] = q9.groupby('ID')['Date'].diff().dt.days

1 个答案:

答案 0 :(得分:1)

我的方法是三个步骤

  1. 获取日期范围
  2. 获取每月支出
  3. 获取类别支出

第1步:日期

date_df = df.groupby('Card_type').Date.apply(lambda x: (x.max()-x.min()).days)

第2步:月

month_df = (df.groupby(['Card_type', df.Date.dt.month_name().str[:3]])
            .Amount
            .agg({'sum','count'})
            .rename({'sum':'_Sp', 'count': '_N'}, axis=1)
            .unstack('Date')
           )

# rename
month_df.columns = [b+a for a,b in month_df.columns]

第3步:类别

cat_df = df.pivot_table(index='Card_type', 
                        columns='Category',
                        values='Amount', 
                        aggfunc='sum')

# rename
cat_df.columns = [a[:2]+"_T" for a in cat_df.columns]

最后是concat

pd.concat( (date_df, month_df, cat_df), axis=1)

给予:

           Date  Feb_Sp  Jan_Sp  Mar_Sp  Feb_N  Jan_N  Mar_N  GR_T  HO_T  RE_T
Card_type                                                                     
GOLD         72    1900    5200    1500      2      5      3  2300  5200  1100
PLATINUM     70    1500    3300    1000      3      5      2  2300  2500  1000
SILVER       76     900    3200    1500      2      5      3  1800  2100  1700

如果您的数据有几年时间,并且想按年份将它们分开,则可以在上面的每个df.Date.dt.year中添加groupby

date_df = df.groupby([df.Date.dt.year,'Card_type']).Date.apply(lambda x: (x.max()-x.min()).days)
month_df = (df.groupby([df.Date.dt.year,'Card_type', df.Date.dt.month_name().str[:3]])
            .Amount
            .agg({'sum','count'})
            .rename({'sum':'_Sp', 'count': '_N'}, axis=1)
            .unstack(level=-1)
           )

# rename
month_df.columns = [b+a for a,b in month_df.columns]

cat_df = (df.groupby([df.Date.dt.year,'Card_type', 'Category'])
            .Amount
            .sum()
            .unstack(level=-1)
         )

# rename
cat_df.columns = [a[:2]+"_T" for a in cat_df.columns]

pd.concat((date_df, month_df, cat_df), axis=1)

给予:

                Date  Feb_Sp  Jan_Sp  Mar_Sp  Feb_N  Jan_N  Mar_N  GR_T  HO_T  
Date Card_type                                                                  
2017 GOLD         72    1900    5200    1500      2      5      3  2300  5200   
     PLATINUM     70    1500    3300    1000      3      5      2  2300  2500   
     SILVER       76     900    3200    1500      2      5      3  1800  2100   
2018 GOLD         72    1900    5200    1500      2      5      3  2300  5200   
     PLATINUM     70    1500    3300    1000      3      5      2  2300  2500   
     SILVER       76     900    3200    1500      2      5      3  1800  2100  

我建议您以这种方式保留数据框,以便您可以访问年度数据,例如result_df.loc[2017]为您提供2017年数据。如果您确实希望将2017作为年份,则可以进行result_df.unstack(level=0)