You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas to_datetime函数行为随Series元素顺序变化的问题

Pandas to_datetime(dayfirst=True) 解析结果随元素顺序变化的问题

问题现象

在验证「日[任意分隔符]月[任意分隔符]年」格式的日期时,使用pd.to_datetime(dayfirst=True, errors='coerce')会出现结果随Series元素顺序变化的异常:

当首元素为数字日期时:

import pandas as pd
foo = pd.Series(['01-01-2023','JAN-01-2023'])
print(pd.to_datetime(foo, dayfirst=True, errors='coerce').notnull())
# 输出:
# 0     True
# 1    False
# dtype: bool

当首元素为带月份缩写的日期时:

foo = pd.Series(['JAN-01-2023','01-01-2023'])
print(pd.to_datetime(foo, dayfirst=True, errors='coerce').notnull())
# 输出:
# 0    True
# 1    True
# dtype: bool

原因分析

这不是bug,而是pd.to_datetime的批量解析逻辑导致的:

  • 批量处理时,pandas会优先根据第一个可成功解析的元素推断全局日期格式,后续所有元素都会沿用这个格式解析。
  • 第一个案例中,首元素01-01-2023结合dayfirst=True被推断为DD-MM-YYYY格式,第二个元素JAN-01-2023不符合该格式(首段是月份缩写而非数字日期),因此被强制转为NaT,返回False。
  • 第二个案例中,首元素JAN-01-2023被明确识别为MMM-DD-YYYY格式,此时dayfirst=True的优先级被覆盖,后续的01-01-2023会按MM-DD-YYYY解析,自然能通过验证。

高性能解决方案

避免使用逐行apply的低性能方案,可通过显式指定所有目标格式让pandas严格按规则解析,而非自动推断:

import pandas as pd
from functools import reduce

def validate_dates(series):
    # 定义所有符合「日[分隔符]月[分隔符]年」的格式,可按需扩展分隔符和格式
    target_formats = [
        '%d-%m-%Y', '%d-%b-%Y',
        '%d/%m/%Y', '%d/%b/%Y',
        '%d.%m.%Y', '%d.%b.%Y'
    ]
    # 用每种格式尝试解析,保留能成功解析的结果
    parsed_dates = [pd.to_datetime(series, format=f, errors='coerce') for f in target_formats]
    # 合并所有解析结果,填充NaN
    combined_dates = reduce(lambda x, y: x.fillna(y), parsed_dates)
    return combined_dates.notnull()

# 测试不同顺序的Series
foo1 = pd.Series(['01-01-2023','JAN-01-2023'])
foo2 = pd.Series(['JAN-01-2023','01-01-2023'])
print(validate_dates(foo1))
print(validate_dates(foo2))
# 两个测试统一输出:
# 0     True
# 1    False
# dtype: bool

该方案保持了pandas的矢量化处理性能,同时严格遵循「日在前」的格式规则,不受元素顺序影响。

内容的提问来源于stack exchange,提问作者Raul Macedo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:42:35