如何基于日期-ID-价格表格按ID计算30日和60日EMA?
解决方案
问题分析
你当前的代码错误地将Date和ID一起分组,导致每个分组仅包含单条价格数据,根本无法计算30日/60日指数移动平均线(EMA)。正确逻辑是仅按ID分组,确保每个分组内是该标的按日期排序的完整价格序列,再进行EMA计算。
正确代码实现
如果你的DataFrame还未按时间排序,先执行排序操作(这是时间序列计算的必要前提):
# 按ID和日期排序,保证每个标的的价格数据按时间顺序排列 df = df.sort_values(by=['ID', 'Date']) # 计算30日、60日EMA并添加为新列 df['EMA_30'] = df.groupby('ID')['Price'].transform(lambda x: x.ewm(span=30, adjust=False).mean()) df['EMA_60'] = df.groupby('ID')['Price'].transform(lambda x: x.ewm(span=60, adjust=False).mean())
代码说明
sort_values:确保每个ID下的日期按时间递增排列,避免因数据顺序混乱导致EMA计算错误。groupby('ID'):单独对每个标的分组,保证EMA基于该标的自身的历史价格计算,不会跨标的混淆数据。transform:将分组计算的EMA结果映射回原DataFrame,直接生成对应行的EMA值,无需额外拼接数据。ewm(span=N, adjust=False):span指定EMA的计算周期,adjust=False采用递归式计算逻辑,符合金融领域常用的EMA算法。
示例输出(基于你的样例数据)
| Date | ID | Price | EMA_30 | EMA_60 |
|---|---|---|---|---|
| 2022-01-01 | Goog | 24 | 24.000 | 24.000 |
| 2022-01-02 | Goog | 28 | 25.935 | 25.967 |
| 2022-01-03 | Goog | 27 | 26.283 | 26.234 |
| 2022-01-01 | META | 46 | 46.000 | 46.000 |
| 2022-01-02 | META | 42 | 43.935 | 43.967 |
| 2022-01-03 | META | 42 | 43.283 | 43.234 |
内容的提问来源于stack exchange,提问作者NFT central
相关产品推荐
相关产品推荐

