Pandas groupby按日期时间数据按月求和

Pandas groupby按日期时间数据按月求和,pandas,pandas-groupby,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 PL

我有一个如下所示的事务数据。这是一个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=三月份的总支出

Jan\u N=一月的交易数量

Feb\u N=2月份的交易数量

GR_T=食品杂货的总支出

Resut=公共设施的总支出

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

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:日期

    date_df = df.groupby('Card_type').Date.apply(lambda x: (x.max()-x.min()).days)
    
    第二步:每月

    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
    
                    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  
    
    如果您的数据有几年,并且您希望按年份将它们分开,那么您可以在上面的每个
    groupby
    中添加
    df.Date.dt.year

    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  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
    
                    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\u df.loc[2017]
    为您提供2017年数据。如果你真的想把2017年作为一年,你可以把结果分解成0级

  • 获取日期范围
  • 得到每月的开销
  • 获取类别支出
  • 步骤1:日期

    date_df = df.groupby('Card_type').Date.apply(lambda x: (x.max()-x.min()).days)
    
    第二步:每月

    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
    
                    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  
    
    如果您的数据有几年,并且您希望按年份将它们分开,那么您可以在上面的每个
    groupby
    中添加
    df.Date.dt.year

    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  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
    
                    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\u df.loc[2017]
    为您提供2017年数据。如果你真的想把2017年作为一年,你可以做
    result\u df.unstack(level=0)

    既然你在苦苦挣扎,你能补充一下你到目前为止已经尝试过的吗?@Valentino当然,事实上我对熊猫还不熟悉。“既然你在挣扎,你能补充一下到目前为止你已经尝试过的吗?”瓦伦蒂诺:当然,事实上,我对熊猫还不熟悉。补充:如果有跨年度的数据,可以计算年度支出。与2017年的支出一样,2018年的支出也是可能的。您可以将所有内容都放入一个函数中,然后对带有年份列的原始数据框执行
    groupby('year')。apply()
    。如果有跨年份的数据,是否可以计算年度支出。与2017年的支出一样,2018年的支出也是可能的。您可以将所有内容都放入一个函数中,然后对带有year列的原始数据框执行
    groupby('year')。apply()