如何在Pandas DataFrame中按组生成移位列并处理首尾行?
问题描述
现有如下Pandas DataFrame:
import pandas as pd data = { 'integer_id': [0, 0, 0, 0, 1, 1, 1], 'begin': [13, 15, 18, 19, 10, 15, 17] } df = pd.DataFrame(data)
需要完成以下操作:
- 生成
end列,值为同integer_id组内下一行的begin值 - 将每组最后一行的
end设为20(注:原描述标注为25,但最终示例结果为20,此处以示例结果为准) - 将每组第一行的
begin截断为10
最终目标结果如下:
integer_id begin end 0 0 10 15 1 0 15 18 2 0 18 19 3 0 19 20 4 1 10 15 5 1 15 17 6 1 17 20
高效实现方法(无需
apply) 相较于groupby+apply的逐组循环方式,用Pandas矢量化操作效率更高,步骤如下:
1. 生成end列
利用groupby结合shift(-1),直接获取每组下一行的begin值,每组最后一行的end会自动赋值为NaN:
df['end'] = df.groupby('integer_id')['begin'].shift(-1)
2. 填充每组最后一行的end值
通过groupby.transform定位每组最后一行,批量赋值为20:
# 标记每组最后一行 is_last_row = df.groupby('integer_id')['integer_id'].transform(lambda x: x == x.iloc[-1]) # 填充目标值 df.loc[is_last_row, 'end'] = 20
3. 修改每组第一行的begin值
同样用transform定位每组第一行,将对应begin值改为10:
# 标记每组第一行 is_first_row = df.groupby('integer_id')['integer_id'].transform(lambda x: x == x.iloc[0]) # 修改目标值 df.loc[is_first_row, 'begin'] = 10
完整代码
import pandas as pd data = { 'integer_id': [0, 0, 0, 0, 1, 1, 1], 'begin': [13, 15, 18, 19, 10, 15, 17] } df = pd.DataFrame(data) # 生成end列 df['end'] = df.groupby('integer_id')['begin'].shift(-1) # 填充每组最后一行的end is_last_row = df.groupby('integer_id')['integer_id'].transform(lambda x: x == x.iloc[-1]) df.loc[is_last_row, 'end'] = 20 # 修改每组第一行的begin is_first_row = df.groupby('integer_id')['integer_id'].transform(lambda x: x == x.iloc[0]) df.loc[is_first_row, 'begin'] = 10 print(df)
运行后即可得到目标结果。
内容的提问来源于stack exchange,提问作者roulette01
相关产品推荐
相关产品推荐

