我想我能猜出发生了什么:In [481]: df=pd.DataFrame( { 'x':[0,0,.1,.2,0,0] } )
In [482]: df2 = pd.rolling_sum(df,window=2)
In [483]: df2
Out[483]:
x
0 NaN
1 0.000000e+00
2 1.000000e-01
3 3.000000e-01
4 2.000000e-01
5 2.775558e-17
看起来还可以,除了最后一个,对吧?事实上,四舍五入已经掩盖了一些其他条目并不像第一眼看上去那么干净。只是默认的显示格式会掩盖这一点,除非你有一个非常接近于零的值。在
^{pr2}$
这里发生的是,滚动总和并不是每次都做一个新的和。相反,它将通过添加最新的数字和删除最旧的数字来更新总和。在这个带有window=2的小例子中,这是没有用的,但是如果窗口大得多,则可以大大加快计算速度,因此这样做是有意义的。在
然而,这意味着会出现一些意想不到的结果。您期望最后一个滚动和是0+0的结果,但实际上不是这样的:In [492]: (.0+.0)+(.1-.0)+(.2-.0)+(.0-.1)+(.0-.2)
Out[492]: 2.7755575615628914e-17
底线:你的结果基本上是好的。只是碰巧你(用这些数据)做的方式揭示了这些事情中固有的潜在精度问题。这种情况经常发生,但默认显示通常会隐藏这些发生在小数点后13位的事情。在
编辑补充:根据Korem的评论,小的负数实际上是一个问题。我认为在这种情况下,最好使用numpy的around函数,并将上面的第二步替换为:df2 = np.around(pd.rolling_sum(df,window=2),decimals=5)
这将迫使所有小数字(正或负)归零。我认为这是一个非常安全的通用解决方案。如果所有的数据都有整数值,你可以将其转换为整数,但显然这不是一个非常通用的解决方案。在