如何在Python DataFrame中按客户分组枚举顾问关联编号
解决DataFrame按客户分组对顾问升序枚举并重置编号的问题
问题场景
你有一个已按日期排序的DataFrame,需要实现:
- 按
Customer分组 - 每个分组内对
Advisor按升序分配唯一编号,相同Advisor对应同一个编号 - 每个
Customer的编号从1重新开始计数
示例数据
先看示例输入和预期输出:
输入DataFrame(已按日期排序)
import pandas as pd df = pd.DataFrame({ 'Date': ['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-01', '2023-01-02'], 'Customer': ['A', 'A', 'A', 'B', 'B'], 'Advisor': ['Bob', 'Alice', 'Bob', 'Charlie', 'Alice'] })
预期输出
# 新增Advisor_Num列后的结果 Date Customer Advisor Advisor_Num 0 2023-01-01 A Bob 2 1 2023-01-02 A Alice 1 2 2023-01-03 A Bob 2 3 2023-01-01 B Charlie 1 4 2023-01-02 B Alice 2
解决方案
核心思路是按Customer分组后,在每个组内对Advisor去重排序,再映射生成从1开始的编号。下面提供两种实现方式:
方法一:分组+自定义函数(清晰易读)
这种方式逻辑直观,便于调试和修改:
def assign_advisor_id(group): # 提取组内唯一Advisor并按字母升序排序 sorted_advs = sorted(group['Advisor'].unique()) # 创建编号映射:排序后的Advisor对应1、2、3... adv_map = {adv: idx+1 for idx, adv in enumerate(sorted_advs)} # 给组内每条数据分配编号 group['Advisor_Num'] = group['Advisor'].map(adv_map) return group # 按Customer分组应用函数,group_keys=False避免额外添加分组索引 df = df.groupby('Customer', group_keys=False).apply(assign_advisor_id)
方法二:分组+transform(简洁版)
用transform直接在原DataFrame上生成结果,代码更紧凑:
df['Advisor_Num'] = df.groupby('Customer')['Advisor'].transform( lambda x: pd.factorize(sorted(x.unique()))[1].map( dict(zip(sorted(x.unique()), range(1, len(sorted(x.unique()))+1))) ) )
常见问题排查
如果之前尝试的groupby方法失效,大概率是因为:
- 没有在每个分组内部单独处理排序和编号生成,而是全局生成了Advisor的编号
- 未对分组内的Advisor进行升序排序,导致编号顺序不符合要求
内容的提问来源于stack exchange,提问作者haraujo
相关产品推荐
相关产品推荐

