Python 在Pandas中应用EWMA滚动窗口功能,但避免初始NAN值
我有以下数据帧和后续EWMA函数: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(
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。不过我很感谢你的帮助!!