You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spark 1.6(Scala+Spark SQL)处理CSV编码字符与脏数据求助

在Spark 1.6(Scala+Spark SQL)中处理CSV乱码与过滤非字母数字行的方案

我来帮你梳理下Spark 1.6环境下的可行解决方案,分两个方向来处理你的问题:

一、先尝试从编码根源解决乱码问题

Spark 1.6本身没有内置CSV数据源,我们通常会用Databricks的spark-csv包来读取CSV文件——这个包其实是支持encoding配置项的,和Spark 2.x的用法类似!你可以试试在读取时指定正确的编码(注意要和原CSV文件的实际编码匹配),示例代码如下:

val df = sqlContext.read
  .format("com.databricks.spark.csv")
  .option("header", "true") // 如果你的CSV有表头就加这个
  .option("encoding", "UTF-8") // 先试试UTF-8,不行的话换ISO-8859-1、GBK等常见编码
  .load("/path/to/your/file.csv")

之前的乱码大概率是因为你指定的编码和原文件不匹配,比如原文件用的是Latin-1编码,你用UTF-8读取就会出现奇怪的字符,多试几种编码应该能解决问题。

二、如果编码问题无法解决,过滤/清理乱码行

你之前用WHERE COL LIKE "^[a-zA-Z0-9]*$"返回0条记录,是因为Spark 1.6的LIKE只支持简单通配符(%_),不支持正则表达式的锚点(^$)。要实现正则匹配过滤,得用Spark SQL的RLIKE函数,或者DataFrame API里的rlike方法。

1. 过滤仅含字母数字的行

如果只想保留地址列全是字母数字的行,可以这样写:

// DataFrame API方式
val filteredDf = df.filter(df("address").rlike("^[a-zA-Z0-9]*$"))

// Spark SQL方式
df.registerTempTable("csv_table")
val filteredDf = sqlContext.sql("SELECT * FROM csv_table WHERE address RLIKE '^[a-zA-Z0-9]*$'")

如果地址里允许空格、连字符这类合法字符,调整正则即可,比如^[a-zA-Z0-9\\s\\-]*$

2. 过滤含不可打印乱码的行

如果乱码是不可见的控制字符,可以用\\p{Print}匹配所有可打印字符,过滤掉包含不可打印字符的行:

val filteredDf = df.filter(df("address").rlike("^[\\p{Print}]*$"))

3. 清理乱码字符(保留有用内容)

如果不想直接过滤行,而是想清理掉乱码字符,可以用regexp_replace函数替换掉非期望的字符:

import org.apache.spark.sql.functions.regexp_replace

val cleanedDf = df.withColumn(
  "cleaned_address",
  regexp_replace(df("address"), "[^a-zA-Z0-9\\s\\-]", "") // 保留字母、数字、空格、连字符,其他替换为空
)

优先推荐先解决编码问题,这是最彻底的方案;如果编码确实无法匹配,再用过滤或清理的方式处理。

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

火山引擎 最新活动