提问人:Question1010 提问时间:11/6/2023 更新时间:11/7/2023 访问量:61
优化移动平均线
Optimize a moving average
问:
我编写了计算每周指数移动平均线的代码,为每天提供一个值。为此,我使用数据帧中每周指数移动平均线的最新值来计算第 “d” 天的值,其中包括截至第 “d” 天的数据
我有以下代码:
def weekly_exponential_moving_average(data: pd.DataFrame, window: int, column: Optional[str] = 'Close_Price') -> pd.Series:
def compute_ema_for_day(day):
day_before_d = data[data.index <= day][column]
weekly_data = day_before_d.resample('W').last()
return weekly_data.ewm(span=window, adjust=False).mean().iloc[-1]
weekly_ema = data.index.to_series().apply(compute_ema_for_day)
return weekly_ema
这给出了所需的结果:它计算 data[column] 窗口上的每周移动平均线。
然而,这段代码是非常不可靠的,因为compute_ema_for_day在整个时间序列中每次都运行。
有没有办法以更有效的方式(如线性时间)计算我想要什么?
答:
0赞
armamut
11/6/2023
#1
我的东西过滤是不必要的。您可以重新采样并返回每周 ema:
def weekly_exponential_moving_average(data: pd.DataFrame, window: int, column: Optional[str] = 'Close_Price') -> pd.Series:
weekly_data = data.resample('W').last()
weekly_ema = weekly_data.ewm(span=window, adjust=False).mean()
return weekly_ema
或者,如果需要与输入相同的形状,则可以将 weekly_ema DataFrame 映射到原始 DataFrame。data
评论
0赞
Question1010
11/6/2023
不,但这不会给出与我上面的函数相同的结果。正如我所说,我每天都有不同的值,您提供的功能显然不是这种情况,因为它在几周内是恒定的
0赞
armamut
11/7/2023
我不明白,因为这一行> weekly_data = day_before_d.resample('W').last() 你能提供样本数据吗
1赞
algebruh
11/7/2023
#2
我认为在大熊猫中没有优雅而快速的方法可以做到这一点。我认为你必须自己编写指数移动平均线类和一个自定义的 for 循环。它可能看起来像这样: (根据一些测试数据,它返回与您的函数相同的值)
import pandas as pd
class ExponentialMovingAverage:
def __init__(self, alpha : float):
self.current_value = None
self.alpha = alpha
def update(self, value, update_current_value = False) -> float:
if self.current_value is None:
self.current_value = value
new_value = self.alpha * value + (1 - self.alpha) * self.current_value
if update_current_value:
self.current_value = new_value
return new_value
def get_ewm_values(ewm: ExponentialMovingAverage, df: pd.DataFrame, column='Close_Price'):
values = []
for index,row in df.iterrows():
sunday_index = 6
day_of_week = index.day_of_week
if day_of_week == sunday_index:
ewm_value = ewm.update(row[column], True)
else:
ewm_value = ewm.update(row[column])
values.append(ewm_value)
return values
emv = ExponentialMovingAverage(0.5)
df['ewm'] = get_ewm_values(emv, df)
评论
0赞
Question1010
11/7/2023
非常感谢您的回答。是的,实际上这可能是唯一的方法,但我没有找到完全相同的结果,例如使用: np.random.seed(0) start_date = datetime(2021, 1, 1) num_dates = 100 date_list = [start_date] for _ in range(num_dates - 1): date_list.append(date_list[-1] + timedelta(days=np.random.randint(1, 4))) close_prices = np.random.rand(num_dates) * 100 df = pd.数据帧({'Close_Price': close_prices}, index=date_list) 打印(df)
0赞
Question1010
11/7/2023
这是因为我的 datframe 中可能缺少日期
0赞
algebruh
11/7/2023
是的,我明白了。然后你需要调整班级。不确定熊猫的实现如何处理不规则采样的系列......只是好奇,你为什么要计算这个?
评论