看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gr99123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在数据整合过程中,我们经常会遇到因系统重复录入、多源采集或时间切片等原因导致的重复记录。直接去重可能丢失有价值的信息,而保留全部又会造成冗余。此时,我们需要根据业务逻辑对重复项进行“智能合并”——即按关键字段分组,并对不同列采用不同的聚合策略(如求和、取最新、拼接等)。本文将通过一个客户订单场景,演示如何结合 groupby、agg 与 first/last 等方法,一次性完成多策略聚合,高效生成干净的主数据表。你将学会如何灵活配置聚合规则,应对真实世界中的复杂去重需求。
假设我们有一张客户订单快照表,包含以下字段:
由于系统每日同步,同一客户可能有多条记录。我们的目标是:
正确结果应满足:
源数据如下:
data = """
customer_id,order_date,total_amount,status,notes
C001,2025-03-10,150.0,shipped,
C001,2025-04-01,200.0,pending,urgent delivery
C002,2025-02-15,300.0,shipped,
C002,2025-02-15,50.0,shipped,gift wrap
C003,2025-05-20,100.0,cancelled,
"""
读取代码:
import pandas as pd
from io import StringIO
df = pd.read_csv(StringIO(data.strip()))
df['order_date'] = pd.to_datetime(df['order_date'])
核心在于使用 groupby('customer_id').agg() 并传入一个字典,为每列指定不同的聚合函数。难点在于:
解决策略:
agg 字典分别定义各列逻辑:idxmax 辅助)但更简洁的方式是:先排序,再用 agg 中对 status 取 'last'(因最新日期排最后),同时自定义 notes 聚合函数。
代码:
import pandas as pd
from io import StringIO
data = """
customer_id,order_date,total_amount,status,notes
C001,2025-03-10,150.0,shipped,
C001,2025-04-01,200.0,pending,urgent delivery
C002,2025-02-15,300.0,shipped,
C002,2025-02-15,50.0,shipped,gift wrap
C003,2025-05-20,100.0,cancelled,
"""
df_clean = (
pd.read_csv(StringIO(data.strip()))
.assign(order_date=lambda x: pd.to_datetime(x['order_date']))
.sort_values(['customer_id', 'order_date']) # 确保组内按日期升序,最新在后
.groupby('customer_id', as_index=False)
.agg(
order_date=('order_date', 'last'), # 最新日期
total_amount=('total_amount', 'sum'),
status=('status', 'last'), # 因已排序,last 即最新状态
notes=('notes', lambda s: '; '.join(s.dropna().astype(str)).strip('; '))
)
)
print(df_clean)
'''
customer_id order_date total_amount status notes
0 C001 2025-04-01 350.0 pending urgent delivery
1 C002 2025-02-15 350.0 shipped gift wrap
2 C003 2025-05-20 100.0 cancelled
'''
代码分析:
sort_values 确保组内 order_date 升序,使 last 能准确取到最新记录;groupby(..., as_index=False) 保持 customer_id 为普通列而非索引;agg 中使用命名元组语法(pandas 0.25+ 支持)清晰映射输入列与聚合逻辑;dropna() 去除空值,再转为字符串并用 '; ' 拼接,避免空字符串干扰;最终输出每个客户一条记录,金额汇总、状态与最新日期一致、备注完整拼接,完美满足业务去重要求。
(完)
更新时间:2025-11-23 09:58:55 标签:pandas python 重复记录 多维指标