我想在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版本
答案 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)