
本文介绍如何使用 Pandas 对数据按 Code 和标准化 Date 双重分组,识别同一代码下日期完全相同的行,并将 'Same_Month' 列统一设为 'Yes',其余保持空白。
本文介绍如何使用 pandas 对数据按 `code` 和标准化 `date` 双重分组,识别同一代码下日期完全相同的行,并将 `'same_month'` 列统一设为 `'yes'`,其余保持空白。
在实际数据分析中,常需根据业务逻辑对重复模式进行标记——例如,当某 Code(如产品编码或客户编号)对应多条记录且其 Date 完全相同时,视为“同月同码”(尽管列名是 Same_Month,但题意实为“同日同码”),需批量打标。本教程提供简洁、高效、可复用的解决方案。
✅ 核心思路
不依赖 groupby().apply() 等低效循环,而是利用 向量化布尔索引:
- 统一解析 Date 为标准 datetime 类型(自动兼容多种格式);
- 基于 ['Code', 'Date'] 联合判断重复项(keep=False 保留所有重复行);
- 直接定位并赋值,零循环、高性能。
? 示例代码(完整可运行)
import pandas as pd
# 构建原始数据
df = pd.DataFrame([
[1,'2023-01-02 00:00:00','01','2023',''],
[2,'2023-01-02 00:00:00','01','2023',''],
[3,'01/16/2023','01','2023',''],
[4,'01/17/2023','01','2023',''],
[5,'01/16/2023','01','2023',''],
[6,'02/13/2023','02','2023',''],
[7,'02/13/2023','02','2023',''],
[8,'02/13/2023','02','2023',''],
[9,'26/11/2018','11','2018',''],
[10,'26/11/2018','11','2018',''],
[11,'26/11/2018','11','2018',''],
[12,'26/11/2018','11','2018',''],
[13,'05/11/2018','11','2018',''],
[14,'09/11/2018','11','2018',''],
], columns=['Number','Date','Code','year','Same_Month'])
# 步骤 1:安全解析日期(自动推断格式,兼容混杂输入)
df['Date'] = pd.to_datetime(df['Date'], format='mixed')
# 步骤 2:标记所有在相同 Code + 相同 Date 下出现 ≥2 次的行
duplicates = df.duplicated(['Code', 'Date'], keep=False)
# 步骤 3:批量赋值(仅更新满足条件的行,其余保持原值)
df.loc[duplicates, 'Same_Month'] = 'Yes'
# 查看结果(仅展示关键列便于验证)
print(df[['Number', 'Date', 'Code', 'year', 'Same_Month']])
⚠️ 注意事项
- format='mixed' 是 Pandas 2.0+ 新增参数,若使用旧版本,请改用 infer_datetime_format=True 或显式指定格式(如 '%m/%d/%Y');
- duplicated(..., keep=False) 是关键:它返回 True 表示该行属于一个重复组(而非仅后续重复项),确保整组都被标记;
- 原始 Same_Month 列若含非空字符串(如 'No'),上述代码不会覆盖——如需清空再赋值,可先执行 df['Same_Month'] = '';
- 本方案严格匹配「日期完全相同」(精确到秒),若业务只需匹配年月,可改用 df['Date'].dt.to_period('M') 后分组。
✅ 总结
该方法以最小代码量实现高可读性与高性能:无需自定义函数、不触发隐式循环、天然支持缺失值与混合日期格式。适用于 ETL 清洗、报表预处理及规则引擎中的条件标记场景。掌握 duplicated() 的联合键与 loc 布尔索引组合,是 Pandas 高阶数据操作的重要基本功。










