滚动最大值不包括 Pandas 中的当前观察值 1.0
Rolling max excluding current observation in Pandas 1.0
使用 Pandas 1.0 我需要使用前 3 个观察值的 window 生成滚动最大值,不包括当前观察值。在 R 中,这是通过
实现的
library(tidyverse)
test_df = data.frame(a = 1:5, b = c(40, 37, 60, 45, 40))
test_df <- test_df %>% mutate(
rolling_max=rollapply(b, width = list(-1:-3), max, na.rm = TRUE, partial = 0, align = "right")
)
> test_df
a b rolling_max
1 1 40 -Inf
2 2 37 40
3 3 60 40
4 4 45 60
5 5 40 60
在 Python 中,pandas.rolling.apply() 函数似乎没有办法排除当前观察,因此这会产生意想不到的结果:
import pandas as pd
test_df = pd.DataFrame({'a': [1,2,3,4,5], 'b': [40,37,60,45,40]})
test_df['rolling_max'] = test_df['b'].rolling(3).apply(max)
test_df
a b rolling_max
0 1 40 NaN
1 2 37 NaN
2 3 60 60.0
3 4 45 60.0
4 5 40 60.0
这输出了预期的结果,但它看起来像是一个笨拙且不可扩展的解决方案:
test_df['rolling_max'] = np.fmax(
test_df['b'].shift(periods=1).to_numpy(),
test_df['b'].shift(periods=2).to_numpy(),
test_df['b'].shift(periods=3).to_numpy()
)
test_df
a b rolling_max
0 1 40 NaN
1 2 37 40.0
2 3 60 40.0
3 4 45 60.0
4 5 40 60.0
有人可以推荐更好的方法吗?
首先,当你说你需要均值时,你正在使用最大值。假设你需要的是max,Python,你可以做如下的事情:
test_df.b.rolling(4, min_periods=2).apply(lambda x: np.max(x[:-1]))
0 NaN
1 40.0
2 40.0
3 60.0
4 60.0
Name: b, dtype: float64
这似乎可以满足您的需求:
test_df.rolling(2, min_periods=1).max()
使用 Pandas 1.0 我需要使用前 3 个观察值的 window 生成滚动最大值,不包括当前观察值。在 R 中,这是通过
实现的library(tidyverse)
test_df = data.frame(a = 1:5, b = c(40, 37, 60, 45, 40))
test_df <- test_df %>% mutate(
rolling_max=rollapply(b, width = list(-1:-3), max, na.rm = TRUE, partial = 0, align = "right")
)
> test_df
a b rolling_max
1 1 40 -Inf
2 2 37 40
3 3 60 40
4 4 45 60
5 5 40 60
在 Python 中,pandas.rolling.apply() 函数似乎没有办法排除当前观察,因此这会产生意想不到的结果:
import pandas as pd
test_df = pd.DataFrame({'a': [1,2,3,4,5], 'b': [40,37,60,45,40]})
test_df['rolling_max'] = test_df['b'].rolling(3).apply(max)
test_df
a b rolling_max
0 1 40 NaN
1 2 37 NaN
2 3 60 60.0
3 4 45 60.0
4 5 40 60.0
这输出了预期的结果,但它看起来像是一个笨拙且不可扩展的解决方案:
test_df['rolling_max'] = np.fmax(
test_df['b'].shift(periods=1).to_numpy(),
test_df['b'].shift(periods=2).to_numpy(),
test_df['b'].shift(periods=3).to_numpy()
)
test_df
a b rolling_max
0 1 40 NaN
1 2 37 40.0
2 3 60 40.0
3 4 45 60.0
4 5 40 60.0
有人可以推荐更好的方法吗?
首先,当你说你需要均值时,你正在使用最大值。假设你需要的是max,Python,你可以做如下的事情:
test_df.b.rolling(4, min_periods=2).apply(lambda x: np.max(x[:-1]))
0 NaN
1 40.0
2 40.0
3 60.0
4 60.0
Name: b, dtype: float64
这似乎可以满足您的需求:
test_df.rolling(2, min_periods=1).max()