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

如何使用Pandera Schema解析含两种格式的datetime列

处理Pandera中包含两种Datetime格式的列

你的场景是数据列同时存在两种时间格式:%Y-%m-%dT%H:%M:%S(带秒)和%Y-%m-%dT%H:%M(不带秒),直接在Pandera的DateTime引擎里指定单一格式会触发 coercion 错误,因为总有部分行匹配不上格式。

原始代码

from pandera.engines import pandas_engine
from pathlib import Path
import io
import pandas as pd
import pandera as pa

# this doesn't work
data = 'date_column\n2020-11-26T02:06:30\n2020-11-22T01:49\n'
df = pd.read_csv(io.StringIO(data))

schema = pa.DataFrameSchema(
        {
            "date_column": pa.Column(
                        pandas_engine.DateTime(
                            to_datetime_kwargs = {
                                "format":"%Y-%m-%dT%H:%M:%S"},
                            tz = "Europe/London")
                        ),
        }, 
        coerce=True
)
new_df = schema.validate(df)

触发的错误

当指定格式为%Y-%m-%dT%H:%M时:

pandera.errors.SchemaError: 
Error while coercing 'date_column' to type datetime64[ns, Europe/London]: 
Could not coerce <class 'pandas.core.series.Series'> data_container into type datetime64[ns, Europe/London]:
   index         failure_case
0      0  2020-11-26T02:06:30

当指定格式为%Y-%m-%dT%H:%M:%S时:

pandera.errors.SchemaError:
Error while coercing 'date_column' to type datetime64[ns, Europe/London]: 
Could not coerce <class 'pandas.core.series.Series'> data_container into type datetime64[ns, Europe/London]:
   index      failure_case
0      1  2020-11-22T01:49

解决方案

方法1:让Pandas自动推断格式

直接移除to_datetime_kwargs里的format参数,Pandas的to_datetime会自动尝试匹配多种格式,同时保留时区设置:

schema = pa.DataFrameSchema(
    {
        "date_column": pa.Column(
            pandas_engine.DateTime(
                tz="Europe/London"
            ),
        ),
    }, 
    coerce=True
)

这种方法最简单,适合大多数场景,但如果数据量极大,自动推断的性能会略低于指定明确格式。

方法2:自定义强制转换函数

如果需要更精准控制(比如明确只有这两种格式,追求性能),可以自定义coerce函数手动处理两种格式:

def coerce_mixed_datetimes(series):
    # 先转换带秒的格式,失败的设为NaN
    with_sec = pd.to_datetime(series, format="%Y-%m-%dT%H:%M:%S", errors="coerce")
    # 对NaN的行转换不带秒的格式
    no_sec = pd.to_datetime(series[with_sec.isna()], format="%Y-%m-%dT%H:%M", errors="coerce")
    # 合并结果并设置时区
    result = with_sec.combine_first(no_sec)
    return result.dt.tz_localize("Europe/London")

schema = pa.DataFrameSchema(
    {
        "date_column": pa.Column(
            pa.DateTime(tz="Europe/London"),
            coerce=coerce_mixed_datetimes
        ),
    }, 
    coerce=True
)

这种方法性能更好,因为只针对已知的两种格式进行转换,避免了Pandas自动推断的额外开销。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 21:55:09