我无法理解pandas.rolling.apply
与np.prod
和NaN的行为。
import pandas as pd
import numpy as np
df = pd.DataFrame({'B': [1, 1, 2, np.nan, 4], 'C': [1, 2, 3, 4, 5]}, index=pd.date_range('2013-01-01', '2013-01-05'))
给出以下 Dataframe :
B C
2013-01-01 1.0 1
2013-01-02 1.0 2
2013-01-03 2.0 3
2013-01-04 NaN 4
2013-01-05 4.0 5
如果我apply
numpy np.prod
函数与raw=False
和min_periods=1
的3天滚动窗口匹配,它将按预期工作,忽略NaN。
df.rolling('3D', min_periods=1).apply(np.prod, raw=False)
B C
2013-01-01 1.0 1.0
2013-01-02 1.0 2.0
2013-01-03 2.0 6.0
2013-01-04 2.0 24.0
2013-01-05 8.0 60.0
然而,对于raw=True
,我在列B中得到NaNs:
df.rolling('3D', min_periods=1).apply(np.prod, raw=True)
B C
2013-01-01 1.0 1.0
2013-01-02 1.0 2.0
2013-01-03 2.0 6.0
2013-01-04 NaN 24.0
2013-01-05 NaN 60.0
我想使用raw=True
来提高速度,但我不明白这种行为。有人能解释一下这是怎么回事吗?
2条答案
按热度按时间yqhsw0fo1#
很简单。你可以试试这个代码
第一个
alen0pnh2#
感谢@padu和@bui提供的评论/答案,让我找到了我一直在寻找的答案,即解释不同的行为。
正如documentation所指出的,当用
raw=False
调用滚动apply
时,每个窗口被转换成一个pandi.Series后才被传递给np.prod
.raw=True
每个窗口被转换成一个numpy数组。关键的观察结果是,
np.prod
在Series上的行为与ndarray上的行为不同,忽略了Series中的NaN,这就是为什么我们会得到不同的行为:np.prod(np.array([1, 2, np.nan, 3]))
得到nan
np.prod(pd.Series([1, 2, np.nan, 3]))
得到6.0
我不清楚为什么在Series中忽略NaN,但是正如@bui指出的,可以通过将
where
关键字设置为np.prod
来忽略ndarray情况下的NaN。