PySpark读取UTF-16编码CSV报DataFrame无OrderID属性错误排查
错误原因
两个核心配置错误导致属性不存在:
- BOM字符未处理引发列名污染:文件为UTF-16 LE BOM编码,读取时仅指定
UTF-16LE编码不会自动跳过文件开头的U+FEFF BOM标记,这个不可见字符会被拼接到第一列的列名前,导致列解析整体偏移。display渲染时会自动隐藏不可见字符,因此肉眼看到的表头和Spark实际存储的列名不一致。 - 错误开启multiline参数导致行解析错位:
multiline=true是CSV读取器用来处理被引号包裹、跨越多行的字段值的配置,当前数据文件每行是一条完整记录,没有跨多行的字段,开启该参数后Spark不会按换行符切分记录,最终导致列和值完全错位——你看到的OrderID表头对应的实际列根本不是存储OrderID值的列,甚至列名本身就因为错位不是OrderID。
额外说明:PySpark的df.列名属性访问方式对列名合法性要求高,列名带特殊字符、隐藏字符时会直接失效,稳定性弱于方括号语法或col()函数。
修复方案
按以下步骤调整代码:
- 删除错误的
option("multiline","true")配置,恢复默认的单行记录解析逻辑 - 读取后自动清除列名中携带的BOM等不可见字符
- 优先使用方括号/
col()语法引用列,避免属性访问的兼容问题
修正后的可运行代码:
from pyspark.sql.types import DoubleType from pyspark.sql.functions import col # 读取文件,移除错误的multiline配置 df = spark.read.option("encoding","UTF-16LE")\ .csv("abfss://mycontainder@myAzureStorageAccount.dfs.core.windows.net/myFolder/MySampleDataFile.txt", sep='~', escape="\"", header="true", inferSchema="false") # 清除列名中可能存在的BOM、前后空白字符 for old_col in df.columns: new_col = old_col.replace("\ufeff", "").strip() if old_col != new_col: df = df.withColumnRenamed(old_col, new_col) # 验证列名后执行类型转换,调试阶段可打开print(df.columns)确认列名正确性 df1 = df.withColumn("OrderID", col("OrderID").cast(DoubleType()))
如果修复后仍有解析问题,可以在读取时追加option("ignoreLeadingWhiteSpace", "true")和option("ignoreTrailingWhiteSpace", "true")配置,自动忽略字段前后的空白字符。
内容的提问来源于stack exchange,提问作者nam
相关产品推荐
相关产品推荐

