【问题标题】:DataFrame: Moving average with rolling, mean and shift while ignoring NaNDataFrame:在忽略 NaN 的情况下使用滚动、均值和移位移动平均
【发布时间】:2018-04-06 03:15:38
【问题描述】:

我有一个数据集,比如说 420x1。现在我要计算过去 30 天的移动平均值,不包括当前日期。

如果我执行以下操作:

df.rolling(window = 30).mean().shift(1)

我的 df 导致一个包含大量 NaN 的窗口,这可能是由原始数据帧中的 NaN 引起的(30 个数据点中的 1 个 NaN 导致 MA 为 NaN)。

是否有忽略 NaN 的方法(避免应用方法,我在大数据上运行它,所以性能是关键)?我不想用 0 替换该值,因为这可能会扭曲结果。

这同样适用于移动标准差。

【问题讨论】:

  • 实际 30 天?工作日?样本数据在哪里?
  • 仅捕获工作日;所以我之前需要 30 行的“偏移量”。
  • 您仍然没有提供任何示例数据。
  • 抱歉,您也可以使用 R.yan 的示例数据。就是这样

标签: pandas dataframe missing-data moving-average


【解决方案1】:

比如你可以加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

【讨论】:

  • 谢谢,温。如果我使用 min_periods = 1,这是否意味着程序使用 29 个观测值来计算平均值?
【解决方案2】:

选项 1

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

选项 2

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

选项 2.5

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

选项 3

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

选项 3.5

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

【讨论】:

  • 谢谢,piRSquared,我认为选项 3 和 3.5 正是我想要的。与 R.yan 相同的问题:当应用 np.nanmean 时,窗口是否仍然存在,即 3、3、NaN 或 NaN 是否被丢弃并使用 NaN 之后的值(或者因为我们正在回顾第一个之前的值3)?
  • 假设窗口为 30,如果 10 是 nan,它将找到其他 20 的平均值。
  • min_periods 是规范的;使用 apply 效率很低 fyi
  • @eternity1 根据 Jeff 的评论,你能接受 wen 的回答吗?谢谢。
【解决方案3】:

您可以尝试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
  • 那么 (3+3+NaN)/3 = 2,是你想要的吗?
  • 是的,因为窗口,即这里是 3,它应该考虑 NaN,而不是在那里为这个特定的窗口计算取另一个值
猜你喜欢
  • 1970-01-01
  • 2022-01-07
  • 2021-11-23
  • 2014-11-29
  • 2013-12-22
  • 2018-09-15
相关资源
最近更新 更多