numpy Pandas滚动应用以意想不到的方式返回NaN

lndjwyie  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(134)

我有一个dataframe,其中一列包含NaN,我试图找到该列中有效数字的滚动平均值。我尝试使用滚动应用,使用自定义函数并传递滚动窗口raw。我见过的替代方案是用0替换NaN,但据我所知,这会人为地缩小我的平均值(更多的条目,相同的总和,更小的平均值)。

import pandas as pd
import numpy as np

mySpecialNumber = 50

def nanMean(arr):
    return arr[~np.isnan(arr)].mean()

df = pd.read_csv('myfile.csv')
df['rollingAVG'] = df['nanColumn'].rolling(mySpecialNumber).apply(nanMean, raw=True)

字符串
上面用NaN值填充df['rollingAVG'],只有NaN。而我可以用途:

singleAVG = nanMean(df['nanColumn'][0:mySpecialNumber].values)


并得到一个完全合理的平均值,准确地反映了手工计算。
希望这不是复制品;我在附近找不到其他类似的东西,所以我怀疑我一定是在偷懒。我也愿意接受那些仍然能产生我想要的结果的替代方案,但这似乎是我能找到的最直接的方法。
我在macOS 13.4.1上运行python 3.11.4,pandas 2.0.3和numpy 1.25.0。
先谢了。

**编辑:**正如我以前尝试使用的建议

df['rollingAVG'] = df['nanColumn'].rolling(mySpecialNumber).mean()


以及

df['rollingAVG'] = df['nanColumn'].rolling(mySpecialNumber).apply(np.mean, raw=True)


但问题依然存在; df['rollingAVG']仍然充满NaN。
我还可以保证数组中充满了NaN;我不只是查看第一个或最后50个条目,我已经设置了np.set_printoptions(threshold=sys.maxsize),并且可以验证df['rollingAVG'].values是一个充满NaN的~1300个条目的数组。

hivapdat

hivapdat1#

您应该为min_periods提供一个值。请检查pandas documentation,以获取.rolling()函数中的此参数:
min_periods:int,default None窗口中需要有值的最小观测数;否则,结果为np.nan
对于由偏移量指定的窗口,min_periods将默认为1。对于由整数指定的窗口,min_periods将默认为窗口的大小。
在本例中,min_periods默认为窗口大小,即mySpecialNumber的值,如果窗口中的50个值中有任何一个值为NaN,则输出为NaN。请看这个例子:

df = pd.DataFrame({'a': [None, 2, 3]})

In [12]: df.rolling(3)['a'].mean()
Out[12]: 
0   NaN
1   NaN
2   NaN
Name: a, dtype: float64

字符串
如果传递min_periods,您将开始看到输出:

In [13]: df.rolling(3, min_periods=1)['a'].mean()
Out[13]: 
0    NaN
1    2.0
2    2.5
Name: a, dtype: float64


我建议将min_periods设置为对您的数据集有意义的值,具体取决于可能丢失的值的数量。

相关问题