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类型设计规范的方案:
- 填充阶段使用默认格式可识别的日期值填充空值,保证列类型保持为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"})
- 最终输出前,统一将日期格式化为业务要求的
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
相关产品推荐
相关产品推荐

