【问题标题】:Pandas group hourly data into daily sums with date indexPandas 将每小时数据分组为带有日期索引的每日总和
【发布时间】:2023-03-20 06:42:01
【问题描述】:

我正在编写一个代码,该代码获取一个月的每小时数据并将其分组为 24 小时总和。我的问题是我希望索引读取日期/年份,而我只是得到一个 1-30 的索引。

我使用的代码是

df = df.iloc[:,16:27].groupby([lambda x: x.day]).sum()

我得到的输出示例

DateTime     data
1            1772.031568
2            19884.42243
3            28696.72159
4            24906.20355
5            9059.120325

我想要的输出示例

DateTime     data
1/1/2017     1772.031568
1/2/2017     19884.42243
1/3/2017     28696.72159
1/4/2017     24906.20355
1/5/2017     9059.120325

【问题讨论】:

    标签: python python-3.x pandas dataframe


    【解决方案1】:

    这是一个老问题,但我认为在这种特殊情况下,公认的解决方案并不是最好的。您想要完成的是对时间序列数据进行下采样,Pandas 对此具有内置功能,称为resample()。对于您的示例,您将执行以下操作:

    df = df.iloc[:,16:27].resample('D').sum()
    

    或者如果日期时间列不是索引

    df = df.iloc[:,16:27].resample('D', on='datetime_column_name').sum()
    

    与公认的答案相比,这样做有(至少)两个好处:

    1. resample 可以上采样和下采样,groupby() 只能下采样
    2. 不需要 lambda、列表解析或日期格式化函数。

    有关更多信息和示例,请参阅此处的文档:resample()

    【讨论】:

    • 这是一个更优雅的答案,也是最新的
    【解决方案2】:

    首先,您需要在 datetime 列上创建一个索引,以公开有效地将 datetime 分解为更小的部分的函数(比如 datetime 的年份和月份)。

    接下来,如果您想对一年中的每一天应用聚合方法(如sum()),则需要按索引的年、月和日分组,并为每一天保留单独的聚合。

    reset_index()rename() 函数允许我们将 group_by 类别重命名为其原始名称。这会“扁平化”我们的数据,使类别成为结果数据帧上的实际列。

    import pandas as pd
    
    date_index = pd.DatetimeIndex(df.created_at)
    # 'df.created_at' is the datetime column in your dataframe
    counted = df.group_by([date_index.year, date_index.month, date_index.day])\
                .agg({'column_to_sum': 'sum'})\
                .reset_index()\
                .rename(columns={'level_1': 'year',
                                 'level_2': 'month',
                                 'level_3': 'day'})
    
    # Resulting dataframe has columns "column_to_sum", "year", "month", "day" available
    

    【讨论】:

      【解决方案3】:

      如果您的索引不是日期时间对象。

      import pandas as pd
      df = pd.DataFrame({'data': [1772.031568, 19884.42243,28696.72159, 24906.20355,9059.120325]},index=[1,2,3,4,5])
      print df.head()
      rng = pd.date_range('1/1/2017',periods =len(df.index), freq='D')
      df.set_index(rng,inplace=True)
      print df.head()
      

      将导致

                 data
      1   1772.031568
      2  19884.422430
      3  28696.721590
      4  24906.203550
      5   9059.120325
                          data
      2017-01-01   1772.031568
      2017-01-02  19884.422430
      2017-01-03  28696.721590
      2017-01-04  24906.203550
      2017-01-05   9059.120325
      

      【讨论】:

        【解决方案4】:

        你可以利用panda的DatetimeIndex:

        working_df=df.iloc[:, 16:27]
        result = working_df.groupby(pd.DatetimeIndex(working_df.DateTime)).date).sum()
        

        如果您的 DateTime 列实际上是 DateTime(并注意时区),则此选项。

        通过这种方式,您将在索引中拥有有效的日期时间,以便您可以轻松地进行其他操作。

        【讨论】:

          【解决方案5】:

          如果您的索引是datetime,您可以构建一个组合的groupby 子句:

          df = df.iloc[:,16:27].groupby([lambda x: "{}/{}/{}".format(x.day, x.month, x.year)]).sum()
          

          甚至更好:

          df = df.iloc[:,16:27].groupby([lambda x: x.strftime("%d%m%Y")]).sum()
          

          【讨论】:

          • 为了记录,我建议您将groupby 标记设置为%Y%m%d,因为这样更容易获得按日期排序的元素(如果您需要的话)。
          猜你喜欢
          • 2011-07-09
          • 2020-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-05-31
          • 2021-06-13
          • 2018-11-12
          • 2019-10-21
          相关资源
          最近更新 更多