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

如何让Pandas使用read_excel读取XLSX时连贯解析日期?

解决Pandas读取Excel时日期列混合类型的问题

你的date列同时存在datetime.datetime对象和字符串格式的日期(如18/12/2022),导致无法直接进行比较操作。以下是几种能让Pandas连贯解析日期、统一列类型的解决方案:

方案1:读取时自定义日期解析规则

通过parse_dates参数指定要解析的列,配合自定义解析函数处理混合格式:

import pandas as pd
from datetime import datetime

def parse_mixed_dates(date_val):
    # 已为datetime对象则直接返回
    if isinstance(date_val, datetime):
        return date_val
    # 定义可能的日期格式,按需扩展
    date_formats = ['%Y-%m-%d', '%d/%m/%Y', '%m/%d/%Y']
    for fmt in date_formats:
        try:
            return datetime.strptime(date_val, fmt)
        except ValueError:
            continue
    # 无法解析的返回NaT(缺失日期)
    return pd.NaT

# 读取Excel时指定解析date列
df = pd.read_excel("example.xlsx", parse_dates=["date"], date_parser=parse_mixed_dates)

处理完成后,date列会统一为datetime64类型,可直接进行比较:

df = df[df["date"] > datetime(2023, 1, 1)]

方案2:读取后统一转换列类型

如果已经读取了数据,可通过pd.to_datetime批量转换列,自动识别混合格式:

import pandas as pd

# 先读取,关闭自动日期解析
df = pd.read_excel("example.xlsx", parse_dates=False)

# 转换date列,自动识别多种格式,无法解析的转为NaT
df["date"] = pd.to_datetime(df["date"], format="mixed", errors="coerce")

# 正常执行比较操作
df = df[df["date"] > "2023-01-01"]

若已知具体格式,也可手动指定格式列表提升效率:

df["date"] = pd.to_datetime(df["date"], format=["%Y-%m-%d", "%d/%m/%Y"], errors="coerce")

方案3:读取时用converters强制转换

通过converters参数为指定列设置转换函数,逐个处理单元格值:

import pandas as pd
from datetime import datetime

def convert_date(val):
    if isinstance(val, datetime):
        return val
    try:
        # 优先解析日/月/年格式
        return datetime.strptime(val, "%d/%m/%Y")
    except (ValueError, TypeError):
        # 其他情况交给pd.to_datetime处理,失败返回NaT
        return pd.to_datetime(val, errors="coerce")

df = pd.read_excel("example.xlsx", converters={"date": convert_date})

以上方法都能将date列统一为标准的日期类型,彻底解决混合类型导致的比较错误。优先推荐在读取阶段处理,减少后续数据清洗步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:22:51