Python 在Pandas中应用EWMA滚动窗口功能,但避免初始NAN值

Python 在Pandas中应用EWMA滚动窗口功能,但避免初始NAN值,python,pandas,Python,Pandas,我有以下数据帧和后续EWMA函数: from functools import partial #Create DF d = {'Name': ['Jim', 'Jim','Jim','Jim','Jim','Jim','Jim','Jim',], 'col2': [5,5,5,5,5,5,5,5]} df1 = pd.DataFrame(data=d) #EWMA 5 alpha = 1-np.log(2)/3 window5 = 5 weights5 = list(reversed(

我有以下数据帧和后续EWMA函数:

from functools import partial

#Create DF
d = {'Name': ['Jim', 'Jim','Jim','Jim','Jim','Jim','Jim','Jim',], 'col2': [5,5,5,5,5,5,5,5]}
df1 = pd.DataFrame(data=d)


#EWMA 5
alpha = 1-np.log(2)/3 
window5 = 5
weights5 = list(reversed([(1-alpha)**n for n in range(window5)]))
ewma5 = partial(np.average, weights=weights5)

df1['Rolling5'] = df1.groupby('Name')['col2'].transform(lambda x: x.rolling(5).apply(ewma5))
df1
其结果是:

我有一个指定的滚动窗口为5,但有人知道如何让EWMA在第一到第四行进行计算,即使没有5个值

例如,对于第1行,只计算第1行(这将是相同的值),然后对于第2行,它计算第1行和第2行的EWMA。也可以采用更有效的方法


非常感谢

您可以使用
ewm
并将
rolling
中的
min\u periods
设置为1:

def f(x):
    return x.ewm(alpha=1-np.log(2)/3).mean().iloc[-1]

df1['Rolling5'] = df1.groupby('Name')['col2'].transform(
    lambda x: x.rolling(5, min_periods=1).apply(f))

与原件相比:

df1['Rolling5_original'] = df1.groupby('Name')['col2'].transform(
    lambda x: x.rolling(5).apply(ewma5))

df1['Rolling5'] = df1.groupby('Name')['col2'].transform(
    lambda x: x.rolling(5, min_periods=1).apply(f))

df1
输出:

  Name  col2  Rolling5_original  Rolling5
0  Jim     1                NaN  1.000000
1  Jim     2                NaN  1.812315
2  Jim     3                NaN  2.736992
3  Jim     4                NaN  3.710959
4  Jim     5           4.702821  4.702821
5  Jim     6           5.702821  5.702821
6  Jim     7           6.702821  6.702821
7  Jim     8           7.702821  7.702821

您可以使用
ewm
并将
rolling
中的
minu periods
设置为1:

def f(x):
    return x.ewm(alpha=1-np.log(2)/3).mean().iloc[-1]

df1['Rolling5'] = df1.groupby('Name')['col2'].transform(
    lambda x: x.rolling(5, min_periods=1).apply(f))

与原件相比:

df1['Rolling5_original'] = df1.groupby('Name')['col2'].transform(
    lambda x: x.rolling(5).apply(ewma5))

df1['Rolling5'] = df1.groupby('Name')['col2'].transform(
    lambda x: x.rolling(5, min_periods=1).apply(f))

df1
输出:

  Name  col2  Rolling5_original  Rolling5
0  Jim     1                NaN  1.000000
1  Jim     2                NaN  1.812315
2  Jim     3                NaN  2.736992
3  Jim     4                NaN  3.710959
4  Jim     5           4.702821  4.702821
5  Jim     6           5.702821  5.702821
6  Jim     7           6.702821  6.702821
7  Jim     8           7.702821  7.702821

如果指定
min\u periods=1
,则
滚动的窗口将从大小1开始,然后扩展到5并保持不变。至于平均数,我们将通过权重的相应部分来覆盖其不足的情况:

weights = (1-alpha) ** np.arange(5)[::-1]

df["rolling_5"] = (df.col2
                     .rolling(5, min_periods=1)
                     .apply(lambda win: np.average(win, weights=weights[-win.size:]))
)
得到

  Name  col2  rolling_5
0  Jim     5        5.0
1  Jim     5        5.0
2  Jim     5        5.0
3  Jim     5        5.0
4  Jim     5        5.0
5  Jim     5        5.0
6  Jim     5        5.0
7  Jim     5        5.0

如果指定
min\u periods=1
,则
滚动的窗口将从大小1开始,然后扩展到5并保持不变。至于平均数,我们将通过权重的相应部分来覆盖其不足的情况:

weights = (1-alpha) ** np.arange(5)[::-1]

df["rolling_5"] = (df.col2
                     .rolling(5, min_periods=1)
                     .apply(lambda win: np.average(win, weights=weights[-win.size:]))
)
得到

  Name  col2  rolling_5
0  Jim     5        5.0
1  Jim     5        5.0
2  Jim     5        5.0
3  Jim     5        5.0
4  Jim     5        5.0
5  Jim     5        5.0
6  Jim     5        5.0
7  Jim     5        5.0


除非我误解了,否则我认为OP希望每个组(名称)计算ewm。此外,这也失去了5不的窗口?@HenryEcker我认为你是对的(在这两方面),我本来就错过了。在这个更新版本中修复了!干得好!很好的呼叫带来了内置的功能。非常感谢-非常好!除非我误解了,否则我认为OP希望每个组(名称)计算ewm。此外,这也失去了5不的窗口?@HenryEcker我认为你是对的(在这两方面),我本来就错过了。在这个更新版本中修复了!干得好!很好的呼叫带来了内置的功能。非常感谢-非常好!非常感谢!Aydin我将如何使用
名称
对一个组执行此操作?ThanksI获得
类型错误:尝试
df1[“rolling_5”]=(df1.groupby('Name')['col2'])时插入列的索引与框架索引不兼容。rolling(5,min_periods=1)。apply(lambda-win:np.average(win,weights=weights[-win.size:])
@SOK您可以链接一个
。重置_索引(level=0,drop=True)
在结尾处,从阻止赋值的索引中删除
名称,即
df1[“rolling_5”]=(df1.groupby(“Name”).col2.rolling(5,min_periods=1)。应用(lambda win:np.average(win,weights=weights[-win.size:])。重置索引(level=0,drop=True))
。谢谢。是的,我正在尝试应用滚动5 winow,但我有多个名称,因此需要将其用于
groupby
。在我接受的答案中,数据帧中有不同的数字,因此不是常数5。不过我很感谢你的帮助!!非常感谢!Aydin我将如何使用
名称
对一个组执行此操作?ThanksI获得
类型错误:尝试
df1[“rolling_5”]=(df1.groupby('Name')['col2'])时插入列的索引与框架索引不兼容。rolling(5,min_periods=1)。apply(lambda-win:np.average(win,weights=weights[-win.size:])
@SOK您可以链接一个
。重置_索引(level=0,drop=True)
在结尾处,从阻止赋值的索引中删除
名称,即
df1[“rolling_5”]=(df1.groupby(“Name”).col2.rolling(5,min_periods=1)。应用(lambda win:np.average(win,weights=weights[-win.size:])。重置索引(level=0,drop=True))
。谢谢。是的,我正在尝试应用滚动5 winow,但我有多个名称,因此需要将其用于
groupby
。在我接受的答案中,数据帧中有不同的数字,因此不是常数5。不过我很感谢你的帮助!!