如何使用toDF()将自定义Java类对象的RDD转换为DataFrame?

时间:2017-04-27 17:23:51

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

我正在尝试使用toDF()将Spark RDD转换为Spark SQL数据帧。我已成功多次使用此函数,但在这种情况下,我收到编译器错误:

error: value toDF is not a member of org.apache.spark.rdd.RDD[com.example.protobuf.SensorData]

以下是我的代码:

// SensorData is an auto-generated class
import com.example.protobuf.SensorData
def loadSensorDataToRdd : RDD[SensorData] = ???

object MyApplication {
  def main(argv: Array[String]): Unit = {

    val conf = new SparkConf()
    conf.setAppName("My application")
    conf.set("io.compression.codecs", "com.hadoop.compression.lzo.LzopCodec")
    val sc = new SparkContext(conf)

    val sqlContext = new org.apache.spark.sql.SQLContext(sc)
    import sqlContext.implicits._

    val sensorDataRdd = loadSensorDataToRdd()
    val sensorDataDf = sensorDataRdd.toDF() // <-- CAUSES COMPILER ERROR
  }
}

我猜测问题出在SensorData类上,这是一个从Protocol Buffer自动生成的Java类。如何将RDD转换为数据帧?

1 个答案:

答案 0 :(得分:3)

编译错误的原因是,范围内没有IDEncoderRDD转换为com.example.protobuf.SensorData Dataset

com.example.protobuf.SensorData(确切地说Encoders)用于根据模式(通常是案例类或Java bean)将ExpressionEncoders对象转换为JVM对象。

希望您可以使用InternalRow对象的Encoder方法为自定义Java类创建org.apache.spark.sql.Encoders

  

为类型为T的Java Bean创建编码器。

如下所示:

bean

如果import org.apache.spark.sql.Encoders implicit val SensorDataEncoder = Encoders.bean(classOf[com.example.protobuf.SensorData]) 使用不受支持的类型,您必须SensorData map RDD[SensorData]个更简单的类型,例如字段的元组,然后只能期望RDD工作。