drop_duplicates() 默认不识别仅日期部分相同的重复,因其按完整时间戳值判断;需先用 .dt.date 或 .dt.floor('D') 提取日期级标识,再通过 subset 参数去重。

drop_duplicates() 默认不识别日期重复?
因为 drop_duplicates() 对 DatetimeIndex 或含日期的列默认按“值完全相等”判断,但你看到的“重复日期”常是时分秒不同、仅日期部分相同——比如 '2023-01-01 09:30:00' 和 '2023-01-01 14:45:22',它们在 datetime64[ns] 类型下是两个不同值,drop_duplicates() 不会认为重复。
- 先确认是否真重复:用
df['date'].dt.date.value_counts()看日期粒度的频次 - 若只想按“年-月-日”去重,得先构造新列,再传给
subset参数 - 别直接对
DatetimeIndex调用drop_duplicates()——它只作用于索引值本身,不触发日期截断逻辑
按日期(非时间戳)去重的实操写法
核心是把时间戳转成日期级标识,再基于该标识去重。最稳妥的方式是新增一列,避免修改原始时间精度。
- 添加临时列:
df['date_only'] = df['timestamp_col'].dt.date(返回datetime.date对象) - 去重并保留首行:
df.drop_duplicates(subset=['date_only'], keep='first', inplace=True) - 删掉临时列:
df.drop(columns=['date_only'], inplace=True) - 注意:
.dt.date在大数据量下略慢;如追求性能,可用.dt.floor('D')(返回datetime64[ns],更快且可参与计算)
用 index 去重时 date_range 或 timezone 导致的隐性坑
如果你的 DataFrame 以日期为索引,且用了 pd.date_range() 生成,看似连续的日期可能因 timezone 设置或频率不匹配,导致索引值实际不等价。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 检查索引是否真正重复:
df.index.duplicated().sum(),不是看df.index.date的唯一性 - 带 timezone 的索引(如
UTCvsAsia/Shanghai)即使显示相同日期,底层时间戳也不同,drop_duplicates()不会合并 - 解决办法:先统一时区(
df.index = df.index.tz_convert('UTC')),再用.floor('D')截断,最后设为新索引或用于subset
drop_duplicates() + keep='last' 与业务逻辑错位
很多人默认用 keep='first',但真实场景中,“保留最新一条记录”才是需求——比如同一日期有多次传感器上报,要留最后一次。
立即学习“Python免费学习笔记(深入)”;
-
keep='last'是按原始行序取最后出现的,不是按时间大小;如果数据未按时间排序,结果不可控 - 务必先排序:
df.sort_values('timestamp_col', inplace=True),再调用drop_duplicates() - 若 timestamp 列有
NaT,sort_values()默认把它排在最前,可能误留空时间记录;加参数na_position='last'更安全

















