我正在查看有关窗口函数的教程,但我不太明白为什么以下代码会生成NaN.
如果我理解正确,代码会创建一个大小为2的滚动窗口.为什么第一行,第四行和第五行都有NaN?起初,我认为这是因为添加另一个数字的NaN会产生NaN,但是我不知道为什么第二行不会是NaN.
dft = pd.DataFrame({'B': [0, 1, 2, np.nan, 4]},
index=pd.date_range('20130101 09:00:00', periods=5, freq='s'))
In [58]: dft.rolling(2).sum()
Out[58]:
B
2013-01-01 09:00:00 NaN
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 3.0
2013-01-01 09:00:03 NaN
2013-01-01 09:00:04 NaN
Run Code Online (Sandbox Code Playgroud)
Bri*_*uey 17
首先要注意的是,默认情况下会rolling查找要聚合的n-1个先前数据行,其中n是窗口大小.如果不满足该条件,它将返回窗口的NaN.这就是第一行发生的事情.在第四和第五行中,这是因为总和中的一个值是NaN.
如果你想避免返回NaN,你可以传递min_periods=1给窗口中有效观察的最小所需数量减少到1而不是2的方法:
>>> dft.rolling(2, min_periods=1).sum()
B
2013-01-01 09:00:00 0.0
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 3.0
2013-01-01 09:00:03 2.0
2013-01-01 09:00:04 4.0
Run Code Online (Sandbox Code Playgroud)
使用min_periods=1可能会导致滚动窗口中的值出现高方差。删除值的另一种方法是在滚动窗口上NaN使用:fillna
>>> dft.rolling(2).sum().fillna(method='bfill').fillna(method='ffill')
B
2013-01-01 09:00:00 1.0
2013-01-01 09:00:01 1.0
2013-01-01 09:00:02 3.0
2013-01-01 09:00:03 3.0
2013-01-01 09:00:04 3.0
Run Code Online (Sandbox Code Playgroud)
滚动窗口大小为 6 的示例说明了该问题:
>>> dft = pd.DataFrame({'B': [10, 1, 10, 1, 10, 1, 10, 1, 10, 1]}, index=pd.date_range('20130101 09:00:00', periods=10, freq='s'))
>>> dft.rolling(6, min_periods=1).sum()
B
2013-01-01 09:00:00 10.0
2013-01-01 09:00:01 11.0
2013-01-01 09:00:02 21.0
2013-01-01 09:00:03 22.0
2013-01-01 09:00:04 32.0
2013-01-01 09:00:05 33.0
2013-01-01 09:00:06 33.0
2013-01-01 09:00:07 33.0
2013-01-01 09:00:08 33.0
2013-01-01 09:00:09 33.0
>>> dft.rolling(6).sum().fillna(method='bfill')
B
2013-01-01 09:00:00 33.0
2013-01-01 09:00:01 33.0
2013-01-01 09:00:02 33.0
2013-01-01 09:00:03 33.0
2013-01-01 09:00:04 33.0
2013-01-01 09:00:05 33.0
2013-01-01 09:00:06 33.0
2013-01-01 09:00:07 33.0
2013-01-01 09:00:08 33.0
2013-01-01 09:00:09 33.0
Run Code Online (Sandbox Code Playgroud)
虽然 usingmin_periods=1会导致前 5 个值低于 33.0,但 usingfillna会在整个窗口中产生预期的 33.0。根据您的用例,您可能想要使用fillna.
| 归档时间: |
|
| 查看次数: |
10240 次 |
| 最近记录: |