将RDD与Array转换为DataFrame

时间:2017-04-12 14:52:28

标签: scala apache-spark rdd

我有以下RDD

RDD[(Long, Array[(Long, Double)])]

我想将其转换为数据框架。 我使用以下代码

val aStruct = new StructType(Array(
    StructField("id", LongType,nullable = true),
    StructField("neighbors",ArrayType(
        StructType(Array(
            StructField("nid", LongType),
            StructField("distance", DoubleType)
    ))),nullable = true)))
val rowRDD = neighbors.map(p => Row(p._1, p._2))
val neighborsDF = sqlContext.createDataFrame(rowRDD,aStruct)

这个编译正确,但给我一个运行时错误

 Error while encoding: java.lang.RuntimeException: scala.Tuple2$mcJD$sp is not a valid external type for schema of struct<nid:bigint,distance:double>

我的架构不合适吗?

我也尝试了

import spark.implicits._
val neighborsDF = neighbors.toDF()

但是为此我得到以下运行时错误

Exception in thread "main" java.lang.NoSuchMethodError: scala.reflect.api.JavaUniverse.runtimeMirror(Ljava/lang/ClassLoader;)Lscala/reflect/api/JavaMirrors$JavaMirror;

在第i行调用toDF()

我在这里做错了什么? (我期待很多:p)

所以我确实理解了这个问题,我在RDD中有一个元组数组,但我似乎无法找到Spark SQL Schema的Tuple类型

1 个答案:

答案 0 :(得分:0)

正如@T.Gawęda指出的那样,我使用单独版本的Scala进行编译(2.10.6),并且在运行时使用Scala版本2.11.8预构建的Spark 2.1.0。这导致以下错误 Exception in thread "main" java.lang.NoSuchMethodError: scala.reflect.api.JavaUniverse.runtimeMirror(Ljava/lang/ClassLoader;)Lscala/reflect/api/JavaMirrors$JavaMirror;

使用时

neighborsDF = neighbors.toDF()

所以我必须使用正确版本的scala编译我的代码,但由于我使用的库(spark-neighbors)在使用Scala版本2.11.8时会引发编译错误,因此更新我的项目的scala版本并不是真的可能。 所以我决定使用链接Building for Scala 2.10

中的指南构建一个带Scala 2.10.6的Spark版本

所以现在我的Spark运行Scala版本2.10.6并且我使用相同的版本来使用sbt编译我的代码。因此RDD转换为数据帧而没有任何错误。 希望它能帮助其他人