我正在测试日期范围内的模拟,这样我希望在给定日期返回相同数字的计算,不管我计算给定批次的日期范围。
也就是说,如果我将系统调用到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和其他滚动函数执行此操作,这些函数稍微复杂一些。
答案 0 :(得分:1)
使用内置的python decimal
模块。它没有浮点舍入错误。然而,它比浮点数慢。