【问题标题】:Grouping daily data by month in python/pandas while firstly grouping by user id在 python/pandas 中按月对每日数据进行分组,同时首先按用户 ID 分组
【发布时间】:2019-01-02 22:38:32
【问题描述】:

我在 Pandas 数据框中有下表:

date                 user_id  whole_cost  cost1             
02/10/2012 00:00:00        1       1790      12         
07/10/2012 00:00:00        1        364      15         
30/01/2013 00:00:00        1        280      10         
02/02/2013 00:00:00        1        259      24         
05/03/2013 00:00:00        1        201      39         
02/10/2012 00:00:00        3        623       1          
07/12/2012 00:00:00        3         90       0          
30/01/2013 00:00:00        3        312      90         
02/02/2013 00:00:00        5        359      45         
05/03/2013 00:00:00        5        301      34         
02/02/2013 00:00:00        5        359       1          
05/03/2013 00:00:00        5        801      12         
..

该表是使用以下查询从 csv 文件中提取的:

import pandas as pd

newnames = ['date','user_id', 'whole_cost', 'cost1']
df = pd.read_csv('expenses.csv', names = newnames, index_col = 'date')

我必须分析我的用户的个人资料,并为此目的:

我想按月对查询进行分组(对于每个用户 - 它们是数千个),将整个月的查询 whole_cost 相加,例如如果user_id=1 在 2012 年 2 月 10 日的总成本为 1790,成本 1 为 12,而在 2012 年 7 月 10 日的总成本为 364,那么它应该在新表中输入 2154(作为总成本) ) 于 2012 年 10 月 31 日(代表月份的月末端点 - 转换表中的所有日期都将是代表与其相关的整个月份的月末)。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    在 0.14 中,您将能够同时按月和另一列分组:

    In [11]: df
    Out[11]:
                user_id  whole_cost  cost1
    2012-10-02        1        1790     12
    2012-10-07        1         364     15
    2013-01-30        1         280     10
    2013-02-02        1         259     24
    2013-03-05        1         201     39
    2012-10-02        3         623      1
    2012-12-07        3          90      0
    2013-01-30        3         312     90
    2013-02-02        5         359     45
    2013-03-05        5         301     34
    2013-02-02        5         359      1
    2013-03-05        5         801     12
    
    In [12]: df1 = df.sort_index()  # requires sorted DatetimeIndex
    
    In [13]: df1.groupby([pd.TimeGrouper(freq='M'), 'user_id'])['whole_cost'].sum()
    Out[13]:
                user_id
    2012-10-31  1          2154
                3           623
    2012-12-31  3            90
    2013-01-31  1           280
                3           312
    2013-02-28  1           259
                5           718
    2013-03-31  1           201
                5          1102
    Name: whole_cost, dtype: int64
    

    直到 0.14 我认为你坚持做两个 groupbys:

    In [14]: g = df.groupby('user_id')['whole_cost']
    
    In [15]: g.resample('M', how='sum').dropna()
    Out[15]:
    user_id
    1        2012-10-31    2154
             2013-01-31     280
             2013-02-28     259
             2013-03-31     201
    3        2012-10-31     623
             2012-12-31      90
             2013-01-31     312
    5        2013-02-28     718
             2013-03-31    1102
    dtype: float64
    

    【讨论】:

    • 嗯。我认为 0.14 中不需要排序(很确定我已修复)。
    • 嗨,我有点困惑:你的变量'df'是否对应于我的变量'frame'?如果是,则 df 的类型是 DataFrame 而不是 DatetimeIndex (我之前因此收到了消息错误)。如何将“帧”转换为 DatetimeIndex(我从 .csv 文件加载数据)?
    • @jeff 也许我没有在这台机器上更新熊猫。将进行检查(上面的示例不同/没有排序就损坏了)-我认为文档中仍然提到了它。
    • @user3102882 df 是一个数据帧。您希望日期索引是日期时间索引(使用 df.index = pd.to_datetime(df.index, dayfirst=True 或在读取 csv 时执行此操作)
    • @AndyHayden 当我使用 df1.groupby([pd.TimeGrouper(freq='M'), 'user_id'])['whole_cost'].sum() 我收到错误消息'时间grouper 对象不可调用'
    【解决方案2】:

    随着 timegrouper 被弃用,您可以将其替换为 Grouper 以获得相同的结果

    df.groupby(['user_id', pd.Grouper(key='date', freq='M')]).agg({'whole_cost':sum})
    
    df.groupby(['user_id', df['date'].dt.dayofweek]).agg({'whole_cost':sum})
    

    【讨论】:

      猜你喜欢
      • 2013-09-11
      • 2019-04-17
      • 2018-10-07
      • 2013-12-06
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      • 2020-04-15
      • 1970-01-01
      相关资源
      最近更新 更多