PySpark如何正确读取CSV文件中的特殊字符避免乱码
问题根因
乱码核心是编码配置和文件实际编码不匹配:
- 你遇到的三个特殊字符:长破折号
–(U+2013)、左单弯引号‘(U+2018)、右单弯引号’(U+2019)不属于ISO-8859-1字符集范围。ISO-8859-1是单字节编码,仅支持0-255码位的字符,上述三个字符码位超出范围,读取时无法识别的字符会被直接替换为?,对应你看到的"Samsung ? 22"、"?World?"类乱码。 - 不配置ISO-8859-1时空格被误读为
–,是因为PySpark默认使用UTF-8编码读取文件,而你的源文件实际编码为Windows-1252(别名cp1252)。该编码是Windows平台对ISO-8859-1的超集,0x80-0x9F码位在ISO-8859-1中为不可见控制字符,在cp1252中恰好对应你遇到的三类特殊字符:0x96对应长破折号–,0x91对应左单弯引号‘,0x92对应右单弯引号’。用UTF-8读取cp1252编码的文件时,上述字节不符合UTF-8编码规则,就会出现字符解析错误。
修复方案
将读取CSV时的encoding参数从ISO-8859-1替换为cp1252即可,cp1252是ISO-8859-1的严格超集,所有ISO-8859-1能正常识别的字符cp1252都可正确解析,不会破坏你之前适配的其他读取场景。
参考读取代码:
from pyspark.sql import SparkSession from pyspark.sql.functions import col spark = SparkSession.builder.appName("csv_read").getOrCreate() df = spark.read \ .option("header", "true") # 按实际需求配置是否读取表头 .option("encoding", "cp1252") \ .csv("你的源CSV文件路径")
如果下游场景需要统一使用UTF-8编码,无需修改读取逻辑,写入文件时指定encoding为UTF-8即可,Spark会自动完成转码。
校验方式
读取完成后可执行以下代码,校验特殊字符是否被正确解析:
# 替换为你实际需要校验的字段名 check_col = "你的目标字段名" df.filter( col(check_col).contains("–") | col(check_col).contains("‘") | col(check_col).contains("’") ).show(truncate=False)
如果校验仍存在乱码,可本地用文本编辑器打开源文件确认实际编码,再对应调整encoding参数即可。绝大多数带英文弯引号、长破折号的西欧语言/英文CSV文件,用cp1252编码均可正常读取。
内容的提问来源于stack exchange,提问作者datadoubts
相关产品推荐
相关产品推荐

