在Spark

时间:2016-05-02 09:55:41

标签: scala exception apache-spark dataframe rdd

我想在DataFrame中向Spark(Scala)添加一个包含行ID的新列。这是我采取的方法。我正在创建一个包含索引ID的新行和一个包含另一个StructType的新StructField

 val rdd = df.rdd.zipWithIndex().map(indexedRow => Row.fromSeq(indexedRow._2.toString ++ indexedRow._1.toSeq ))
 val list = StructType(Seq(StructField("Row Number", StringType, true)).++(df.schema.fields))
 sqlContext.createDataFrame(rdd, list).show() // fails

我跑步时遇到以下异常。

scala.MatchError: 0 (of class java.lang.Character)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$StringConverter$.toCatalystImpl(CatalystTypeConverters.scala:295)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$StringConverter$.toCatalystImpl(CatalystTypeConverters.scala:294)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$CatalystTypeConverter.toCatalyst(CatalystTypeConverters.scala:102)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$StructConverter.toCatalystImpl(CatalystTypeConverters.scala:260)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$StructConverter.toCatalystImpl(CatalystTypeConverters.scala:250)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$CatalystTypeConverter.toCatalyst(CatalystTypeConverters.scala:102)
    at org.apache.spark.sql.catalyst.CatalystTypeConverters$$anonfun$createToCatalystConverter$2.apply(CatalystTypeConverters.scala:401)
    at org.apache.spark.sql.SQLContext$$anonfun$6.apply(SQLContext.scala:492)
    at org.apache.spark.sql.SQLContext$$anonfun$6.apply(SQLContext.scala:492)

但是structtype和rdd具有预期的输出。 谁能帮我这个?请

我尝试过使用Spark2.10 1.6.0和1.6.1版本

2 个答案:

答案 0 :(得分:2)

你只有一个小错误,那就是将字符串值添加到字段序列中 - 而不是:

indexedRow._2.toString ++ indexedRow._1.toSeq

您应该使用:

indexedRow._2.toString +: indexedRow._1.toSeq

第一个实现实际上将字符串转换为Seq[Char],然后连接这两个序列,因此您最终得到Seq('1', '2', "f1Val", "f2Val")而不是Seq("12", "f1Val", "f2Val")之类的内容。您看到的例外是Spark尝试将第一个Char解析为StringType并失败。

答案 1 :(得分:1)

查看this答案,了解为rdd行分配唯一ID的更好方法(RDD.zipWithUniqueId)