
本文介绍如何在 Pandas 中高效地将同一 ID 组内相邻 SEQ 值两两组合(如 "1 - 2"、"2 - 3"),避免冗余列和显式布尔筛选,利用 groupby().shift() 和函数式链式操作实现简洁、可读性强且性能更优的解决方案。
本文介绍如何在 pandas 中高效地将同一 id 组内相邻 seq 值两两组合(如 "1 - 2"、"2 - 3"),避免冗余列和显式布尔筛选,利用 `groupby().shift()` 和函数式链式操作实现简洁、可读性强且性能更优的解决方案。
在处理有序分组序列数据时,常需将同一分组(如 ID)中连续记录的字段(如 SEQ)进行成对组合,例如生成 "当前 SEQ - 下一 SEQ" 的字符串对。传统做法(如先 shift(-1) 再 ID 对齐过滤)会引入临时列、冗余计算和显式布尔索引,既降低可读性,也影响执行效率。
更推荐的做法是使用 分组内前向位移(groupby('ID')['SEQ'].shift()) 配合链式操作(assign + dropna),一步到位完成逻辑。关键在于:shift() 默认向下位移(即取上一行值),因此我们让 SEQ_NEXT 表示“前一行的 SEQ”,再与当前 SEQ 拼接,自然形成 prev - curr 序列对;同时 dropna() 自动剔除每组首行(无前驱值)及跨组边界,无需手动比较 ID。
以下是完整实现代码:
import pandas as pd
x = pd.DataFrame({
'ID': [1, 1, 1, 1, 2, 2, 2],
'SEQ': [1, 2, 3, 4, 1, 3, 4]
})
result = (x.astype({'SEQ': 'str'})
.assign(
SEQ_NEXT=lambda df: df.groupby('ID')['SEQ'].shift(),
COMBINE=lambda df: df['SEQ_NEXT'] + ' - ' + df['SEQ']
)
.dropna(subset=['SEQ_NEXT'])
.reindex(columns=['ID', 'SEQ', 'SEQ_NEXT', 'COMBINE']))
print(result)
输出结果为:
ID SEQ SEQ_NEXT COMBINE 1 1 2 1 1 - 2 2 1 3 2 2 - 3 3 1 4 3 3 - 4 5 2 3 1 1 - 3 6 2 4 3 3 - 4
✅ 优势说明:
- ✅ 无需中间列污染:不创建
ID_NEXT等辅助列,逻辑聚焦于目标字段; - ✅ 自动分组对齐:
groupby('ID').shift()确保仅在同 ID 内部位移,天然规避跨组错误配对; - ✅ 一次
dropna完成过滤:SEQ_NEXT为空即代表该行为组首,直接剔除,比x['ID']==x['ID_NEXT']更语义清晰且高效; - ✅ 支持链式编程:全表达式无副作用,便于嵌入 ETL 流程或函数封装。
⚠️ 注意事项:
- 若需
curr - next(而非prev - curr)格式,可改用shift(-1)并调整dropna条件(如dropna(subset=['SEQ_NEXT'])仍适用,但索引顺序略有不同); -
SEQ列若含非字符串类型,务必提前转为str(如示例中的astype({'SEQ': 'str'})),否则拼接会报错; - 数据必须已按
ID和SEQ排序,否则shift()结果无业务意义——本例中原始数据已满足此前提。
综上,该方法以更少代码、更高可维护性与更好性能,成为 Pandas 中分组序列配对任务的标准实践。










