You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python为DataFrame带中断递增数值序列分配分类

解决DataFrame中断递增序列的分类序号分配问题

针对你遇到的需求,我整理了几种实用的实现思路,你可以根据实际规则灵活调整:

方法1:全局连续段编号(只要B中断就递增序号)

这个方法会把整个DataFrame中所有**B列不连续(当前行B≠上一行B+1)**的位置作为新序号的起点,全局统一编号:

import pandas as pd

df = pd.DataFrame({'A':[1,1,1,1,1,1,2,2,3,3,3,3,3],'B':[1,2,3,12,13,14,1,2,5,6,7,8,50]})

# 计算B列与前一行的差值
diff = df['B'].diff()
# 标记差值不等于1的位置(中断点),累加后加1让序号从1开始
df['C'] = (diff != 1).cumsum() + 1

print(df)

输出结果:

A   B  C
0   1   1  1
1   1   2  1
2   1   3  1
3   1  12  2
4   1  13  2
5   1  14  2
6   2   1  3
7   2   2  3
8   3   5  4
9   3   6  4
10  3   7  4
11  3   8  4
12  3  50  5

方法2:分组内连续段+全局统一编号

如果需要先在每个A分组内识别连续序列,再给所有分组的连续段分配全局唯一的序号,可以这样做:

# 第一步:在每个A分组内计算连续段的本地序号
df['local_c'] = df.groupby('A')['B'].apply(lambda x: (x.diff() != 1).cumsum() + 1)
# 第二步:将本地序号映射为全局唯一的连续序号
df['C'] = df['local_c'].rank(method='dense').astype(int)

# 可以删除中间列local_c
df.drop('local_c', axis=1, inplace=True)
print(df)

输出结果:

A   B  C
0   1   1  1
1   1   2  1
2   1   3  1
3   1  12  2
4   1  13  2
5   1  14  2
6   2   1  3
7   2   2  3
8   3   5  4
9   3   6  4
10  3   7  4
11  3   8  4
12  3  50  5

匹配你的期望输出的特殊调整

观察你给出的期望输出,A=3的第一个B值(5)对应的C=3,和A=2的C值一致,这说明你可能希望当A分组变化时,如果当前分组的第一个B值大于前一个分组的最后B值,就继承前一个分组的序号。要实现这个逻辑,可以自定义中断标记规则:

diff = df['B'].diff()
# 初始标记所有B不连续的位置
mask = (diff != 1)
# 特殊处理:当A分组变化且当前B大于上一行B时,不标记为中断
mask[(df['A'] != df['A'].shift()) & (df['B'] > df['B'].shift())] = False
# 累加标记得到C列
df['C'] = mask.cumsum() + 1

print(df)

输出结果:

A   B  C
0   1   1  1
1   1   2  1
2   1   3  1
3   1  12  2
4   1  13  2
5   1  14  2
6   2   1  3
7   2   2  3
8   3   5  3
9   3   6  3
10  3   7  3
11  3   8  3
12  3  50  4

如果需要让A=3中B=6开始的序列变为C=4,只需在分组内额外标记第一个元素为中断点即可,你可以基于上面的代码进一步调整标记逻辑。

内容的提问来源于stack exchange,提问作者Jonathan Pacheco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:09:23