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

PySpark DateType日期列fillna填充指定格式空值失效问题

问题根因

Spark的DateType类型内部存储的是日期语义的数值,不存在自定义存储格式的属性。调用fillna给DateType列传入字符串填充值时,Spark会默认按yyyy-MM-dd的标准格式尝试将字符串转为日期类型:

  • Code1传入的1900-01-01完全匹配默认解析格式,能成功转成合法DateType值,因此填充生效
  • Code2传入的01/01/1900不符合默认解析规则,转换后为NULL,Spark对fillna中转换失败、类型不匹配的填充值做静默忽略处理,不会抛出报错,最终表现为空值没有被填充。

另外要注意:业务要求的mm/dd/yyyy是日期的展示格式,不是DateType的存储格式,不可能直接在DateType列里存成斜杠分隔的字符串格式。

排查方向
  • 执行df1.printSchema()确认Hiring_date列cast后确实为DateType,排除cast逻辑失效、列实际为StringType的干扰
  • 单独执行spark.sql("SELECT cast('01/01/1900' AS date)").show(),查看返回结果为NULL即可验证字符串格式不匹配默认解析规则的问题
  • 确认业务侧对mm/dd/yyyy的要求是最终输出格式,而非要求DateType列存储该格式的字符串
修复方案

根据业务场景二选一即可:

方案1:先填充标准日期,输出时格式化

这是最符合Spark类型设计规范的方案:

  1. 填充阶段使用默认格式可识别的日期值填充空值,保证列类型保持为DateType,方便后续做日期计算、筛选等操作
from pyspark.sql import functions as F
df1 = df.withColumn("Hiring_date", F.col("Hiring_date").cast("date"))
df2 = df1.fillna({"Hiring_date": "1900-01-01"})
  1. 最终输出前,统一将日期格式化为业务要求的mm/dd/yyyy字符串
df_final = df2.withColumn(
    "Hiring_date",
    F.date_format(F.col("Hiring_date"), "MM/dd/yyyy")
)

方案2:显式转换填充值格式后填充

如果需要直接在填充逻辑中指定01/01/1900作为入参,不要直接传入原始字符串,先显式按mm/dd/yyyy格式将字符串转为DateType,再用coalesce完成空值填充(fillna不支持传列对象作为填充值,因此用coalesce实现等价逻辑):

from pyspark.sql import functions as F
df1 = df.withColumn("Hiring_date", F.col("Hiring_date").cast("date"))
fill_date = F.to_date(F.lit("01/01/1900"), "MM/dd/yyyy")
df2 = df1.withColumn("Hiring_date", F.coalesce(F.col("Hiring_date"), fill_date))
# 后续需要输出斜杠格式时同样调用date_format转换即可

注意:格式化模式中月份要写大写MM,小写mm代表分钟,会导致日期转换/格式化结果错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:30:41