带条件的Pandas Shift操作实现方法求助
问题
我有一个包含ID、tag、value三列的小型数据集,其中tag代表特征value的信息来源。我想要为value创建滞后特征(lag feature),目前已通过简单方法实现,但发现当tag值相同时(如索引5的行)也会执行shift操作,这不符合需求。我希望仅当tag特征值不同时才执行shift操作,请问有什么合适的实现方法?
代码示例
import pandas as pd import numpy as np df = pd.DataFrame({'ID':[1,1,1,2,2, 2,2,3,3,3], 'tag':[10, 11, 15, 11, 12, 12, 13, 16, 17, 18], 'value':[21, 19, 22, 41, 43, 43, 38, 9, 12, 16]}) df['value_lag'] = df.sort_values(by=['ID', 'tag']).groupby('ID')['value'].shift(1) print(df)
当前输出
ID tag value value_lag 0 1 10 21 NaN 1 1 11 19 21.0 2 1 15 22 19.0 3 2 11 41 NaN 4 2 12 43 41.0 5 2 12 43 43.0 6 2 13 38 43.0 7 3 16 9 NaN 8 3 17 12 9.0 9 3 18 16 12.0
期望输出
ID tag value value_lag 0 1 10 21 NaN 1 1 11 19 21.0 2 1 15 22 19.0 3 2 11 41 NaN 4 2 12 43 41.0 5 2 12 43 41.0 -Here, should not be 43 6 2 13 38 43.0 7 3 16 9 NaN 8 3 17 12 9.0 9 3 18 16 12.0
解决方案
要实现仅当tag不同时才生成有效滞后值,可以通过分组基准值映射的方式处理,具体步骤如下:
实现代码
import pandas as pd import numpy as np df = pd.DataFrame({'ID':[1,1,1,2,2, 2,2,3,3,3], 'tag':[10, 11, 15, 11, 12, 12, 13, 16, 17, 18], 'value':[21, 19, 22, 41, 43, 43, 38, 9, 12, 16]}) # 1. 按ID+tag分组,保留每组第一个value作为该tag的基准值 grouped_base = df.groupby(['ID', 'tag'])['value'].first().reset_index() # 2. 对分组后的基准数据按ID生成滞后值,即取前一个不同tag的value grouped_base['value_lag'] = grouped_base.groupby('ID')['value'].shift(1) # 3. 将滞后值合并回原数据集,同tag的所有行共享同一个滞后值 df = df.merge(grouped_base[['ID', 'tag', 'value_lag']], on=['ID', 'tag'], how='left') print(df)
最终输出
ID tag value value_lag 0 1 10 21 NaN 1 1 11 19 21.0 2 1 15 22 19.0 3 2 11 41 NaN 4 2 12 43 41.0 5 2 12 43 41.0 6 2 13 38 43.0 7 3 16 9 NaN 8 3 17 12 9.0 9 3 18 16 12.0
逻辑说明
- 先通过
groupby(['ID', 'tag'])聚合相同ID和tag的行,保留第一个value作为该tag组的基准值,确保同tag下所有行的滞后值来源统一 - 针对基准数据集按ID做shift操作,此时只会在不同tag之间生成滞后值,避免同tag内的无效shift
- 最后用merge将滞后值映射回原数据集,保证同tag的所有行使用相同的滞后值,完全符合需求
内容的提问来源于stack exchange,提问作者Henri
相关产品推荐
相关产品推荐

