【问题标题】:Undo a Series Diff撤消系列差异
【发布时间】:2016-01-21 07:45:08
【问题描述】:

我有一个带有月度数据的熊猫系列 (df.sales)。我需要减去 12 个月前的数据来拟合时间序列,所以我运行了这个命令:

sales_new = df.sales.diff(periods=12)

然后我拟合了一个 ARMA 模型,并预测了未来:

model = ARMA(sales_new, order=(2,0)).fit()
model.predict('2015-01-01', '2017-01-01')

因为我对销售数据进行了差异化,所以当我使用模型进行预测时,它会预测正向差异。如果这是第 1 期的差异,我只会使用np.cumsum(),但因为这是第 12 期,所以它有点棘手。

“展开”差异并将其转回原始数据规模的最佳方法是什么?

【问题讨论】:

  • 能否请您展示一个示例数据框,说明您拥有什么以及您想要的结果是什么?

标签: python pandas difference forecasting statsmodels


【解决方案1】:

我认为您需要根据前 12 个月的值计算未来值:

periods = 12
df = pd.DataFrame(data={'value': np.random.random(size=24)}, index=pd.date_range(start=date(2014, 1,1), freq='M', periods=24))
diffs = df.diff(periods=periods)

restored = df.copy()
restored.iloc[periods:] = np.nan
for d, val in diffs.iloc[periods:].iterrows():
    restored.loc[d] = restored.loc[d - pd.DateOffset(months=periods)].value + val

res = pd.concat([df, diffs, restored], axis=1)
res.columns = ['original', 'diffs', 'restored']

            original     diffs  restored
2014-01-31  0.926367       NaN  0.926367
2014-02-28  0.688898       NaN  0.688898
2014-03-31  0.297025       NaN  0.297025
2014-04-30  0.139094       NaN  0.139094
2014-05-31  0.375082       NaN  0.375082
2014-06-30  0.490638       NaN  0.490638
2014-07-31  0.789683       NaN  0.789683
2014-08-31  0.236841       NaN  0.236841
2014-09-30  0.263245       NaN  0.263245
2014-10-31  0.547025       NaN  0.547025
2014-11-30  0.243444       NaN  0.243444
2014-12-31  0.385028       NaN  0.385028
2015-01-31  0.823224 -0.103142  0.823224
2015-02-28  0.828245  0.139347  0.828245
2015-03-31  0.753291  0.456266  0.753291
2015-04-30  0.447670  0.308576  0.447670
2015-05-31  0.936667  0.561584  0.936667
2015-06-30  0.223049 -0.267589  0.223049
2015-07-31  0.933942  0.144259  0.933942
2015-08-31  0.325726  0.088886  0.325726
2015-09-30  0.947526  0.684281  0.947526
2015-10-31  0.524749 -0.022276  0.524749
2015-11-30  0.431671  0.188227  0.431671
2015-12-31  0.234028 -0.151000  0.234028

【讨论】:

  • 这有帮助吗?
【解决方案2】:

应该这样做:

def rebuild_diffed(series, first_element_original):
    cumsum = series.cumsum()
    return cumsum.fillna(0) + first_element_original

分步版本:

# making some data 
a = pd.Series([2, 6, 4, 6, 2,])
print(a)
a_diff = a.diff()
print(a_diff)

# Rebuilding  
a_diff_cumsum = a_diff.cumsum()
print(a_diff_cumsum)

rebuilt = a_diff_cumsum.fillna(0) + 2
print(rebuilt)

print(rebuilt == a)

【讨论】:

    【解决方案3】:

    要区分,请使用:

    def differentiate(values, d=1):  
        x = np.concatenate([[values[0]], values[1:]-values[:-1]])
        if d != 1:
            return differentiate(x, d - 1)
        else:    
            return x
    

    要集成回来,使用这个:

    def integrate(values, d=1):
        x = np.cumsum(values)
        if d != 1:
            return integrate(x, d-1)
        else:        
            return x
    

    确保您的输入在 numpy 数组中。您还可以更改差异。因此,integrate 功能正是您所寻求的。

    【讨论】:

      【解决方案4】:

      这是针对 Pandas 1.3.3 版的。但我认为它也应该适用于早期版本。

      我遇到了类似的情况,我的数据是每天的,我申请了diff(period=7) 来删除每周的季节性。现在我的模型可以预测差异值。

      假设您的模型预测数据框名为fitted_values_df,其中DatetimeIndex 作为索引的类型。您想展开所有列。以下是我按 7 周期展开的示例:

      fitted_values_df['weekday'] = fitted_values_df.index.weekday
      fitted_values_df.groupby('weekday').cumsum()
      

      我检查了数据,它有效。

      在您的情况下,您可以为groupby 创建一个monthofyear 列(而不是weekday)。

      抱歉,我无法在此处发布我的数据。

      【讨论】:

        猜你喜欢
        • 2015-05-11
        • 2010-10-17
        • 2022-01-06
        • 2011-07-07
        • 2011-11-16
        • 1970-01-01
        • 1970-01-01
        • 2018-01-07
        • 1970-01-01
        相关资源
        最近更新 更多