Pandas滚动应用NaN

t40tm48m  于 2022-12-02  发布在  其他
关注(0)|答案(2)|浏览(153)

我无法理解pandas.rolling.applynp.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=Falsemin_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来提高速度,但我不明白这种行为。有人能解释一下这是怎么回事吗?

yqhsw0fo

yqhsw0fo1#

很简单。你可以试试这个代码
第一个

alen0pnh

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。

相关问题