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

PySpark处理单列多日期格式:如何让无效日期返回NULL?

解决PySpark中多格式日期解析问题

方案1:使用to_date多格式参数(推荐)

Spark 3.0及以上版本支持直接给to_date函数传入格式数组,自动匹配解析,无效日期会返回NULL,无需额外判断:

from pyspark.sql import functions as F

df = df.withColumn(
    "parsed_datdoc",
    F.to_date(F.col("datdoc"), ["dd-MMM-yy", "dd-MMM-yyyy"])
)

这个方法会依次尝试两种格式,匹配成功就解析成日期,都不匹配则返回NULL,完全满足需求。

方案2:修复CASE WHEN判断逻辑

如果要保留CASE WHEN的思路,需要结合容错处理避免报错:

方式A:字符长度判断+容错解析

通过字符串长度区分两种格式,同时用try_cast确保解析失败时返回NULL:

df = df.withColumn(
    "parsed_datdoc",
    F.when(
        F.length(F.col("datdoc")) == 9,
        F.try_cast(F.to_date(F.col("datdoc"), "dd-MMM-yy"))
    ).when(
        F.length(F.col("datdoc")) == 11,
        F.try_cast(F.to_date(F.col("datdoc"), "dd-MMM-yyyy"))
    ).otherwise(F.lit(None))
)

方式B:临时调整解析策略

如果严格模式下解析报错,可临时设置会话级解析策略为LEGACY,让解析失败时返回NULL:

spark.conf.set("spark.sql.legacy.timeParserPolicy", "LEGACY")

df = df.withColumn(
    "parsed_datdoc",
    F.when(
        F.regexp_extract(F.col("datdoc"), r"\d{4}$", 0) != "",
        F.to_date(F.col("datdoc"), "dd-MMM-yyyy")
    ).otherwise(
        F.to_date(F.col("datdoc"), "dd-MMM-yy")
    )
)
# 解析完成后可改回默认的EXCEPTION模式
spark.conf.set("spark.sql.legacy.timeParserPolicy", "EXCEPTION")

方案3:修复自定义change_date_format函数

如果要保留自定义函数,需在函数中加入异常捕获,确保解析失败时返回None(对应Spark中的NULL):

from pyspark.sql.types import DateType
from datetime import datetime

def change_date_format(date_str):
    if not date_str:
        return None
    # 依次尝试两种格式解析
    for fmt in ["%d-%b-%y", "%d-%b-%Y"]:
        try:
            return datetime.strptime(date_str, fmt).date()
        except ValueError:
            continue
    # 所有格式都匹配失败时返回None
    return None

# 注册UDF
change_date_udf = F.udf(change_date_format, DateType())

# 应用到DataFrame
df = df.withColumn("parsed_datdoc", change_date_udf(F.col("datdoc")))

注意:UDF性能不如Spark内置函数,优先推荐方案1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 01:37:11