生日列里同时有 2026/3/1 和 2026-03-01 两种写法,to_datetime 加 errors='coerce' 之后 8 万行有 2.4 万行变成 NaT,入库全为空,控制台一条警告都没有。日志里能对上时间点,这种反而好排。

解析器默认按第一行推断格式,后面格式不一致的值直接判失败。coerce 把异常吞成 NaT,统计时只看到空值率变高,看不到原始报错。这一点先确认清楚,后面就不用反复试。

df = pd.read_csv(path, dtype=str)
d = pd.to_datetime(df['birth'], format='mixed', errors='coerce')
bad = df[d.isna() & df['birth'].notna()]

「日期格式混用」排查到最后往往是很小的一处差异,前面那些复杂猜测可以先放一放。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。

别只看报错的最后一行,往上看几行,真正的起因通常在上面。同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。

处理上按这个顺序:pandas 2.0 以上显式写 format='mixed' 让它逐值推断;低版本先按分隔符分两批解析 再合并结果;把转换失败的原始字符串单独落一张表 便于回溯。

结果对不对很好判断,NaT 行数从 2.4 万降到 0,bad 表里只剩原本就为空的 37 行,抽样日期与源文件一致。

作者 9823189