如何对DataFrame中ID按递减1连续序列的行分组?
问题描述
现有如下DataFrame:
| ID | Column B |
|---|---|
| 10 | item 1 |
| 10 | item 1 |
| 10 | item 1 |
| 9 | item 2 |
| 8 | item 3 |
| 8 | item 3 |
| 8 | item 3 |
| 8 | item 3 |
| 7 | item 4 |
| 6 | item 5 |
| 4 | item 6 |
| 4 | item 6 |
| 5 | item 7 |
| 5 | item 7 |
需要新增result列,分组规则为:仅将ID构成递减1的连续序列的行归为同一组,预期结果如下:
| ID | Column B | result |
|---|---|---|
| 10 | item 1 | 1 |
| 10 | item 1 | 1 |
| 10 | item 1 | 1 |
| 9 | item 2 | 1 |
| 8 | item 3 | 1 |
| 8 | item 3 | 1 |
| 8 | item 3 | 1 |
| 8 | item 3 | 1 |
| 7 | item 4 | 1 |
| 6 | item 5 | 1 |
| 4 | item 6 | 2 |
| 4 | item 6 | 2 |
| 5 | item 7 | 2 |
| 5 | item 7 | 2 |
之前尝试的代码df["result"] = (df["X2"] > df["X2"].shift(1)).cumsum()无法得到正确结果,需要修正。
解决方案
要实现这个分组逻辑,核心是判断当前行ID与前一行ID的关系:当两者为同一ID,或当前ID比前一行ID小1时,归为同一组;其他情况则开启新分组。具体实现代码如下:
import pandas as pd # 构造原始DataFrame data = { "ID": [10,10,10,9,8,8,8,8,7,6,4,4,5,5], "Column B": ["item 1"]*3 + ["item 2"] + ["item 3"]*4 + ["item 4"] + ["item 5"] + ["item 6"]*2 + ["item 7"]*2 } df = pd.DataFrame(data) # 生成分组标记:当ID与前一行既不是相同,也不是递减1时,标记为新分组 group_flag = ~((df["ID"] == df["ID"].shift(1)) | (df["ID"] == df["ID"].shift(1) - 1)) # 通过累计求和得到result分组列,+1让分组从1开始计数 df["result"] = group_flag.cumsum() + 1 print(df)
代码说明
df["ID"].shift(1):将ID列向下偏移一行,用于和当前行ID做对比;(df["ID"] == df["ID"].shift(1)):判断当前行与前一行是否为同一ID;(df["ID"] == df["ID"].shift(1) - 1):判断当前行ID是否比前一行ID小1(即递减1);~(...):对上述条件取反,得到所有需要开启新分组的行;group_flag.cumsum():对分组标记累计求和,再+1让分组编号从1开始。
运行后即可得到符合预期的result列。
内容的提问来源于stack exchange,提问作者Ayan
相关产品推荐
相关产品推荐

