Numpy,pandas,Matlab,R滚动和不一致,具有不同的历史长度

时间:2015-01-29 04:03:38

标签: matlab numpy pandas numerical-methods moving-average

我正在测试日期范围内的模拟,这样我希望在给定日期返回相同数字的计算,不管我计算给定批次的日期范围。

也就是说,如果我将系统调用到1990-2000的范围,那么1995.07.01的结果应该与调用系统1995-1996时的结果相同。应该是非常基本的,我想......

问题是快速滚动窗口实现会累积舍入错误,这取决于滚动窗口之外的历史记录长度。因此,当我在1995.07.01进行20天的移动总和时,结果将在1990年以来的时间序列上运行滚动求和操作时产生更多的累积舍入误差。

这是一个例子,我希望非纳米结果完全匹配:

df = pd.DataFrame([xrange(7)]).astype('float64').T
df = np.sqrt(df)
roll1_df = pd.rolling_sum(df, window=3)
roll2_df = pd.rolling_sum(df.iloc[3:, :], window=3)

但是我得到了舍入错误:

roll1_df - roll2_df

              0
0           NaN
1           NaN
2           NaN
3           NaN
4           NaN
5  8.881784e-16
6  1.776357e-15

这个例子是使用Python / pandas,但问题在任何数字运算软件中都是一样的,因此我很高兴在熊猫,numpy,Matlab,R ......或基于纯理论的想法。

保持快速滚动操作的性能优势是很重要的,即避免简单地对所有日期的最后N个值求和(比快速滚动窗口实现慢O(N)倍)。

编辑:解决方案

毕竟我选择了以下解决方案,将熊猫分开并将其与roll_sum中的一些舍入放在一起:

rolling_sum_stable_df = _rolling_func(
    lambda *arg_l: np.round(roll_sum(*arg_l), decimals=11),
    'Stable rolling_sum'
)

可以在rolling_sum()之前先转换为float32,然后转换回float64,但会丢失更多的数字。这种方法的缺点是我必须为rolling_cov和其他滚动函数执行此操作,这些函数稍微复杂一些。

1 个答案:

答案 0 :(得分:1)

使用内置的python decimal模块。它没有浮点舍入错误。然而,它比浮点数慢。