【问题标题】:How to aggregate irregularly sampled data for Time Series Analysis如何为时间序列分析聚合不规则采样的数据
【发布时间】:2021-05-25 05:28:10
【问题描述】:

我正在尝试使用时间序列分析来预测每日利润,但每日利润不仅记录不均,而且部分数据缺失。

原始数据:

Date Revenue
2020/1/19 10$
2020/1/20 7$
2020/1/25 14$
2020/1/29 18$
2020/2/1 12$
2020/2/2 17$
2020/2/9 28$

上表是我拥有的数据类型的示例。利润不是每天记录的,因此 2020/1/20 和 2020/1/24 之间的日期不存在。不仅如此,假设在 2020/2/3 和 2020/3/8 期间记录的利润在数据库中丢失了。我想恢复这个丢失的数据,并使用时间序列分析来预测2020/2/9之后的利润~。

我的方法是首先每 6 天汇总一次利润,因为我必须在 2020/2/3 和 2020/3/8 之间收回利润。所以我清理后的数据看起来像这样

Date Revenue
2020/1/16 ~ 2020/1/21 17$
2020/1/22 ~ 2020/1/27 14$
2020/1/28 ~ 2020/2/2 47$
2020/2/3 ~ 2020/2/8 ? (to predict)

将此应用于时间序列模型后,我想进一步预测 2020/2/9 之后的利润~。 这是我的一般想法,但作为 Python 的初学者,使用 pandas 库时,我在执行我的想法时遇到了麻烦。能否请您帮我如何汇总每 6 天的利润,并让数据如上表所示?

【问题讨论】:

    标签: python pandas dataframe time-series data-science


    【解决方案1】:

    最简单的方法是使用 pandas resample 函数。

    如果您有一个Datetime 类型的索引,每 6 天重新采样一次以汇总利润将像 your_dataframe.resample('6D').sum() 一样简单

    您可以进行各种重采样(月末、季度末、周初、每小时、每分钟、每秒钟……)。如果您有兴趣,请查看完整文档:https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.resample.html?highlight=resample#pandas.DataFrame.resample

    【讨论】:

      【解决方案2】:

      我建议使用.rolling、pd.date_range 和.reindex 的组合

      假设您的 DataFrame 是 df,并带有正确的日期时间索引:

      df = pd.DataFrame([['2020/1/19',10],
                         ['2020/1/20',7],
                         ['2020/1/25',14],
                         ['2020/1/29',18],
                         ['2020/2/1',12],
                         ['2020/2/2',17],
                         ['2020/2/9',28]],columns=['Date','Revenue'])
      
      df['Date'] = pd.to_datetime(df['Date'])
      df.set_index('Date',inplace=True)
      

      第一步是用虚拟的零收入“填补”缺失的日子。我们可以使用pd.date_range 得到一个从 2020/1/16 到 2020/2/8 等间距日期的索引,然后使用.reindex 将其带入主df DataFrame:

      evenly_spaced_idx = pd.date_range(start='2020/1/16',end='2020/2/8',freq='1d')
      df = df.reindex(evenly_spaced_idx, fill_value=0)
      

      现在我们可以对每 6 天的时间段进行滚动计算。不过,我们对每天六天的总收入不感兴趣,只对每六天的总收入感兴趣:

      summary_df = df.rolling('6d').sum().iloc[5::6, :]
      

      summary_df 的最后一件事就是按照您喜欢的方式对其进行格式化,以便清楚地说明每行所指的日期范围。

      summary_df['Start Date'] = summary_df.index-pd.Timedelta('6d')
      summary_df['End Date'] = summary_df.index
      summary_df.reset_index(drop=True,inplace=True)
      

      【讨论】:

        【解决方案3】:

        您可以为此使用resample。

        确保将“日期”列设置为日期时间类型。

        >>> df = pd.DataFrame([["2020/1/19"  ,10],
            ... ["2020/1/20"  ,7],
            ... ["2020/1/25"  ,14],
            ... ["2020/1/29"  ,18],
            ... ["2020/2/1"  ,12],
            ... ["2020/2/2"  ,17],
            ... ["2020/2/9"  ,28]], columns=['Date', 'Revenue'])
        >>> df['Date'] = pd.to_datetime(df.Date)
        

        对于熊猫

        >>> df.set_index('Date').resample('6D', base=3).sum()
                    Revenue
        Date
        2020-01-16       17
        2020-01-22       14
        2020-01-28       47
        2020-02-03        0
        2020-02-09       28
        

        对于熊猫 >= 1.1.0

        >>> df.set_index('Date').resample('6D', origin='2020-01-16').sum()
                    Revenue
        Date
        2020-01-16       17
        2020-01-22       14
        2020-01-28       47
        2020-02-03        0
        2020-02-09       28
        

        【讨论】:

          猜你喜欢
          • 2010-11-04
          • 2015-04-10
          • 2023-01-20
          • 2016-06-22
          • 2019-05-27
          • 1970-01-01
          • 1970-01-01
          • 2013-03-03
          • 2012-01-30
          相关资源
          最近更新 更多