如何按时间线出现顺序为唯一对象生成连续编号
按时间线顺序为首次出现的对象分配唯一编号
问题背景
你需要处理一个按时间线B排序后的DataFrame,为A列中首次出现的新对象分配递增的编号,后续重复出现的对象沿用之前的累计编号(即保持当前已出现的唯一对象总数),最终结果存入C列。
给定的排序后DataFrame:
import pandas as pd import numpy as np df = pd.DataFrame({'A':[700,701,701,702,800,800,800,801],'B':[2,3,5,6,8,1,7,4]}).sort_values(by=['B'])
排序后的数据:
A B 5 800 1 0 700 2 1 701 3 7 801 4 2 701 5 3 702 6 6 800 7 4 800 8
期望得到的结果:
A B C 5 800 1 1 0 700 2 2 1 701 3 3 7 801 4 4 2 701 5 4 3 702 6 5 6 800 7 5 4 800 8 5
你之前方法的问题
你尝试用shift()比较相邻行的A值,再用cumsum()生成编号,但这种方法只判断了当前行和前一行是否不同,无法识别非连续出现的重复对象(比如示例中第6行的800和第5行的800间隔了多行),会导致错误地将重复对象判定为新对象,打乱编号逻辑。
正确解决方案
我们需要先判断每个A是否是在整个DataFrame中首次出现,再对这个标记做累计求和,就能得到符合要求的C列。具体代码如下:
# 标记每个A是否为首次出现 df['is_first'] = ~df['A'].duplicated() # 对首次出现标记做累计求和,生成C列 df['C'] = df['is_first'].cumsum() # 可选:删除临时辅助列 df = df.drop('is_first', axis=1)
原理解释
~df['A'].duplicated():duplicated()会标记出重复出现的A值(首次出现的为False,后续重复为True),取反~后就得到了首次出现的标记(首次为True,重复为False)。cumsum():布尔值在求和时会被转换为1(True)和0(False),累计求和的结果就是截至当前行已出现的唯一对象总数——遇到新对象时总数加1,重复对象时总数保持不变,完全匹配你的需求。
运行后得到的结果和你期望的完全一致!
内容的提问来源于stack exchange,提问作者ProcolHarum
相关产品推荐
相关产品推荐

