Python 数据帧的所有值的滚动平均值

Python 数据帧的所有值的滚动平均值,python,pandas,numpy,Python,Pandas,Numpy,我有一个熊猫数据框,我想在滚动的基础上计算所有值的平均值:对于所有列,对于滚动窗口中的所有观察值 我有一个循环解决方案,但感觉效率很低。请注意,我的数据中可以有NaNs,因此计算总和并除以窗口的形状是不安全的(因为我需要nanmean) 还有更好的办法吗 设置 import numpy as np import pandas as pd np.random.seed(1) df = pd.DataFrame(np.random.randint(0, 10, size=(10, 2)), co

我有一个熊猫数据框,我想在滚动的基础上计算所有值的平均值:对于所有列,对于滚动窗口中的所有观察值

我有一个循环解决方案,但感觉效率很低。请注意,我的数据中可以有
NaNs
,因此计算总和并除以窗口的形状是不安全的(因为我需要
nanmean

还有更好的办法吗

设置

import numpy as np
import pandas as pd

np.random.seed(1)

df = pd.DataFrame(np.random.randint(0, 10, size=(10, 2)), columns=['A', 'B'])

df[df>5] = np.nan  # EDIT: add nans
我的尝试

n_roll = 2

df_stacked = df.values
roll_avg = {}
for idx in range(n_roll, len(df_stacked)+1):
    roll_avg[idx-1] = np.nanmean(df_stacked[idx - n_roll:idx, :].flatten())

roll_avg = pd.Series(roll_avg)
roll_avg.index = df.index[n_roll-1:]
roll_avg = roll_avg.reindex(df.index)
roll_avg
Out[33]: 
0         NaN
1    5.000000
2    1.666667
3    0.333333
4    1.000000
5    3.000000
6    3.250000
7    3.250000
8    3.333333
9    4.000000
期望的结果

n_roll = 2

df_stacked = df.values
roll_avg = {}
for idx in range(n_roll, len(df_stacked)+1):
    roll_avg[idx-1] = np.nanmean(df_stacked[idx - n_roll:idx, :].flatten())

roll_avg = pd.Series(roll_avg)
roll_avg.index = df.index[n_roll-1:]
roll_avg = roll_avg.reindex(df.index)
roll_avg
Out[33]: 
0         NaN
1    5.000000
2    1.666667
3    0.333333
4    1.000000
5    3.000000
6    3.250000
7    3.250000
8    3.333333
9    4.000000

谢谢

为了在出现
nan
的情况下获得相同的结果,您可以在所有
df.shift(i)上使用
column\u stack
。范围(n\u roll)
中i的值,使用轴=1上的
nanmean
,然后您需要在以下时间之后将第一个
n\u roll-1
值替换为
nan

roll_avg = pd.Series(np.nanmean(np.column_stack([df.shift(i).values for i in range(n_roll)]),1))
roll_avg[:n_roll-1] = np.nan
使用第二个输入
nan
,您可以得到预期的结果

0         NaN
1    5.000000
2    1.666667
3    0.333333
4    1.000000
5    3.000000
6    3.250000
7    3.250000
8    3.333333
9    4.000000
dtype: float64

这里有一个带滑动窗口的NumPy解决方案
view\u as\u windows
-

from skimage.util.shape import view_as_windows

# Setup o/p array
out = np.full(len(df),np.nan)

# Get sliding windows of length n_roll along axis=0
w = view_as_windows(df.values,(n_roll,1))[...,0]

# Assign nan-ignored mean values computed along last 2 axes into o/p
out[n_roll-1:] = np.nanmean(w, (1,2))
In [62]: np.shares_memory(df,w)
Out[62]: True
查看
视图时的内存效率-

from skimage.util.shape import view_as_windows

# Setup o/p array
out = np.full(len(df),np.nan)

# Get sliding windows of length n_roll along axis=0
w = view_as_windows(df.values,(n_roll,1))[...,0]

# Assign nan-ignored mean values computed along last 2 axes into o/p
out[n_roll-1:] = np.nanmean(w, (1,2))
In [62]: np.shares_memory(df,w)
Out[62]: True
使用注释中引用的注释,可以执行以下操作:

wsize = n_roll
cols = df.shape[1]
out = group.stack(dropna=False).rolling(window=wsize * cols, min_periods=1).mean().reset_index(-1, drop=True).sort_index()
out.groupby(out.index).last()
out.iloc[:nroll-1] = np.nan
在我的例子中,在
stack
中指定
dropna=False
非常重要,否则滚动窗口的长度将不正确


但我期待其他方法,因为这感觉不太优雅/高效。

可能有用。您可以使用
.shift
,也可以堆叠并滚动到更大的窗口上。非常感谢您的回答。我有没有办法避免使用撇渣法?似乎不包括在标准anaconda分发/my current中environment@FLab您可以使用@FLab或使用:
np.nanmean(跨步轴0(df.values,n\u roll),(1,2))
。感谢它使用跨步轴0。我刚刚注意到,如果窗口中的所有值都是nan,那么我有一个RuntimeWarning:代码导入InteractiveConsole的空片段的平均值,这似乎会影响时间性能,因此它不如“堆栈”解决方案I的速度快posted@FLab不确定警告如何影响性能。在顶部关闭警告怎么样?