Spark-shell:列数不匹配

时间:2019-01-20 23:22:09

标签: scala apache-spark apache-spark-sql

我有csv格式的文件,并由定界符“ |”分隔。数据集有2列,如下所示。

Column1|Column2
1|Name_a
2|Name_b

但是有时我们仅收到一个列值,而其他值则如下所示丢失

Column1|Column2
1|Name_a
2|Name_b
3
4
5|Name_c
6
7|Name_f

因此,对于上面的示例,任何具有不匹配的列号的行都是无用的值,对于我们来说,它将是列值为3, 4, and 6的行,我们希望丢弃这些行。有什么直接的方法可以丢弃这些行,而不会像下面这样从spark-shell读取数据时出现异常。

val readFile = spark.read.option("delimiter", "|").csv("File.csv").toDF(Seq("Column1", "Column2"): _*)

当我们尝试读取文件时,出现以下异常。

java.lang.IllegalArgumentException: requirement failed: The number of columns doesn't match.
Old column names (1): _c0
New column names (2): Column1, Column2
  at scala.Predef$.require(Predef.scala:224)
  at org.apache.spark.sql.Dataset.toDF(Dataset.scala:435)
  ... 49 elided 

2 个答案:

答案 0 :(得分:1)

您可以指定数据文件的架构,并允许某些列为空。在scala中,它可能看起来像:

val schm = StructType(
  StructField("Column1", StringType, nullable = true) ::
  StructField("Column3", StringType, nullable = true) :: Nil)

val readFile = spark.read.
option("delimiter", "|")
.schema(schm)
.csv("File.csv").toDF

比您可以按列过滤数据集的方法不为空。

答案 1 :(得分:0)

在阅读时,只需将DROPMALFORMED模式添加到以下选项中即可。设置此设置可使Spark删除损坏的记录。

val readFile = spark.read
  .option("delimiter", "|")
  .option("mode", "DROPMALFORMED") // Option to drop invalid rows.
  .csv("File.csv")
  .toDF(Seq("Column1", "Column2"): _*)

已记录在here中。