Pandas DataFrame分组移位:生成3期历史列的实现方案
问题描述
现有如下Pandas DataFrame:
Sym C O R 01.01.2020 AAPL 100 115 0.2 01.01.2020 AA 200 205 0.4 02.01.2020 AAPL 101 116 0.3 02.01.2020 AA 201 206 0.2 02.01.2020 MM 298 300 0.5 03.01.2020 AAPL 110 105 0.3 03.01.2020 AA 203 204 0.1 03.01.2020 MM 301 303 0.2 04.01.2020 AAPL 108 113 0.3 04.01.2020 AA 200 201 0.4 04.01.2020 MM 302 300 0.3
需要生成一个新的DataFrame,为每个Sym分组的前3期数据创建对应新列(如C_1、O_1等),预期结果如下:
Sym C_1 O_1 R_1 C_2 O_2 R_2 C_3 O_3 R_3 01.01.2020 AAPL NaN NaN ... NaN 01.01.2020 AA NaN NaN ... NaN 02.01.2020 AAPL 100 115 0.2 NaN NaN NaN NaN NaN NaN 02.01.2020 AA 200 205 0.4 NaN NaN NaN NaN NaN NaN 02.01.2020 MM NaN NaN ... NaN 03.01.2020 AAPL 101 116 0.3 100 115 0.2 NaN NaN NaN 03.01.2020 AA 201 206 0.2 200 205 0.4 NaN NaN NaN 03.01.2020 MM 298 300 0.5 NaN NaN .. NaN 04.01.2020 AAPL 101 116 0.3 100 115 0.2 110 105 0.3 04.01.2020 AA 203 204 0.1 201 206 0.2 200 205 0.4 04.01.2020 MM 301 303 0.2 298 300 0.5 Nan NaN NaN
尝试以下代码未实现需求:
def shift_data (df): df= df.shift(3) return df data.groupby('Sym', group_keys=False).apply(shift_data)
解决方案
可以通过分组后循环生成滞后列的方式实现,步骤如下:
- 先处理日期索引并排序,确保分组内数据按时间顺序排列:
import pandas as pd # 将字符串索引转为datetime类型 data.index = pd.to_datetime(data.index, format='%d.%m.%Y') # 按Sym和日期排序,保证分组内数据的时间顺序正确 data = data.sort_values(['Sym', data.index])
- 定义需要生成的滞后期数,循环为每个特征生成对应滞后列:
# 需要生成前3期数据,所以设置n_shifts=3 n_shifts = 3 for i in range(1, n_shifts + 1): # 对每个分组的C、O、R列做shift(i)操作,获取前i期数据 shifted_cols = data.groupby('Sym')[['C', 'O', 'R']].shift(i) # 重命名列名,格式为"列名_期数" shifted_cols.columns = [f'{col}_{i}' for col in shifted_cols.columns] # 将生成的滞后列合并到原DataFrame中 data = pd.concat([data, shifted_cols], axis=1)
- 调整列顺序并恢复原始日期排序:
# 定义目标列顺序:先保留Sym,再按C_1、O_1、R_1...C_3、O_3、R_3排列 target_cols = ['Sym'] + [f'{col}_{i}' for i in range(1, n_shifts+1) for col in ['C', 'O', 'R']] # 按原始日期索引排序,恢复初始的日期顺序 data = data.sort_index()[target_cols]
执行后即可得到符合预期的结果,其中C_1表示当前行对应Sym的前1期C值,C_2是前2期数据,不足的部分自动填充NaN。
内容的提问来源于stack exchange,提问作者Beginner_01
相关产品推荐
相关产品推荐

