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

PySpark读取CSV时badRecordsPath生效后DataFrame计数异常问题

问题解答

这是预期行为吗?

是的,这是PySpark结合badRecordsPath时的预期行为。具体原因:

  • Spark读取CSV时默认使用PERMISSIVE(容错)模式,当你指定badRecordsPath但未修改模式时,所有Schema不匹配的坏记录会被写入指定的坏数据路径,但这些记录并不会被从DataFrame中移除,而是被保留为所有字段值都是null的行。
  • 所以df.show()看不到有效内容(全是null),而df.count()统计的是包含这些null行的总行数,和原文件行数一致。

怎么获取正确的有效数据计数?

有两种实用方法:

方法1:手动过滤全null记录

通过filter筛选出至少有一个字段非null的记录,再统计数量:

# 示例:假设schema包含col1、col2、col3三个字段
valid_df = df.filter(df.col1.isNotNull() | df.col2.isNotNull() | df.col3.isNotNull())
print(valid_df.count())

# 如果字段较多,可以动态生成过滤条件,不用逐个写
from pyspark.sql.functions import col
valid_df = df.filter(" OR ".join([f"{col_name}.isNotNull()" for col_name in df.columns]))
print(valid_df.count())

方法2:设置mode="DROPMALFORMED"自动过滤

读取文件时加上mode="DROPMALFORMED"参数,Spark会自动过滤掉Schema不匹配的坏记录,同时把这些坏记录写入badRecordsPath,此时df.count()直接返回有效数据的行数:

df = (
    spark.read.format(file_type)
    .schema(schema)
    .option("badRecordsPath", f"/tmp/badrecords/")
    .option("header", True)
    .option("encoding", "iso-8859-1")
    .option("sep", ",")
    .option("mode", "DROPMALFORMED")  # 新增该参数
    .load(file_path)
)
print(df.count())  # 此时返回的就是有效数据的数量
df.show()  # 仅显示有效数据

两种方式的区别:PERMISSIVE模式保留null行(方便后续排查),DROPMALFORMED直接过滤坏记录,可根据业务需求选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:12:05