DataFrame: 移动平均值计算,采用滚动、均值和位移方式,同时忽略 NaN 值。

3
我是一位有用的助手,可以为您翻译文本。
我有一个数据集,假设是420x1。现在我想计算过去30天的移动平均值,不包括当前日期。
如果我这样做:
df.rolling(window = 30).mean().shift(1)

我的df结果显示有很多NaN,这可能是由于原始数据框中有一些NaN导致的(30个数据点中的1个NaN会导致MA为NaN)。

是否有一种方法可以忽略NaN(避免使用apply方法,因为我在大型数据上运行它,所以性能至关重要)?我不想用0替换值,因为那可能会扭曲结果。

同样适用于移动标准差。


1
30个实际天?工作日?样本数据在哪里? - piRSquared
只捕获工作日;因此我需要在之前“偏移”30行。 - eternity1
你仍然没有提供任何样本数据。 - piRSquared
抱歉,您也可以使用R.yan的示例数据。它正是那个。 - eternity1
3个回答

7
例如,您可以添加min_periods,然后NaN就会消失。
df=pd.DataFrame({'A':[1,2,3,np.nan,2,3,4,np.nan]})
df.A.rolling(window=2,min_periods=1).mean()

Out[7]: 
0    1.0
1    1.5
2    2.5
3    3.0
4    2.0
5    2.5
6    3.5
7    4.0
Name: A, dtype: float64

谢谢,Wen。如果我使用min_periods = 1,这是否意味着程序使用29个观测值来计算平均值? - eternity1

2

选项一

df.dropna().rolling('30D').mean()

选项二

df.interpolate('index').rolling('30D').mean()

Option 2.5

df.interpolate('index').rolling(30).mean()

Option 3

s.rolling('30D').apply(np.nanmean)

Option 3.5

df.rolling(30).apply(np.nanmean)

谢谢,piRSquared,我认为选项3和3.5更符合我的需求。同样的问题也问给R.yan:在应用np.nanmean时,窗口是否仍然是3、3、NaN,还是NaN被删除,然后使用NaN后面的值(或者因为我们正在回顾第一个3之前的值,所以使用第一个3之前的值)? - eternity1
假设窗口大小为30,如果其中有10个值为nan,则计算其他20个值的平均数。 - piRSquared
2
min_periods是规范的;使用apply效率相当低,供您参考。 - Jeff
@eternity1 根据Jeff的评论,你能接受wen的答案吗?谢谢。 - piRSquared

1
你可以尝试 dropna() 来删除 nan 值,或者使用 fillna() 将 nan 替换为特定值。
或者在操作中使用 notnull()isnull() 过滤掉所有的 nan 值。
df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f', 'h'],columns=['one', 'two', 'three'])
df2 = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
print df2
        one       two     three
a  0.434024 -0.749472 -1.393307
b       NaN       NaN       NaN
c  0.897861  0.032307 -0.602912
d       NaN       NaN       NaN
e -1.056938 -0.129128  1.328862
f -0.581842 -0.682375 -0.409072
g       NaN       NaN       NaN
h -1.772906 -1.342019 -0.948151

df3 = df2[df2['one'].notnull()]
# use ~isnull() would return the same result
# df3 = df2[~df2['one'].isnull()]
print df3
    one       two     three
a  0.434024 -0.749472 -1.393307
c  0.897861  0.032307 -0.602912
e -1.056938 -0.129128  1.328862
f -0.581842 -0.682375 -0.409072
h -1.772906 -1.342019 -0.948151

作为进一步参考,Pandas有一份关于处理缺失数据的详细文档(请阅读this)。


谢谢建议。我不想放弃观察,也不想用另一个值来填充它(除非没有其他办法)。这就像计算平均值,但忽略缺失的值(3 + 3 + NaN)/ 2 = 3,而不是(3 + 3 + 0)/ 3 = 2。 - eternity1
所以 (3+3+NaN)/3 = 2,这是你想要的吗? - R.yan
是的,由于窗口大小为3,应该考虑NaN,而不是在此特定窗口计算中采用另一个值。 - eternity1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接