隐藏在Spark Scala程序中无法正常工作

时间:2017-05-31 16:53:42

标签: scala apache-spark implicits

虽然我正在导入spark.implicits._,但我无法在Scala程序中执行从RDD到Dataframe的隐式转换。

任何帮助都将不胜感激。

主要程序含有:

object spark1 {

  def main(args: Array[String]) {
    val spark = SparkSession.builder().appName("e1").config("o1", "sv").getOrCreate()

    import spark.implicits._

    val conf = new SparkConf().setMaster("local").setAppName("My App")
    val sc = spark.sparkContext
    val data = sc.textFile("/TestDataB.txt")
    val allSplit = data.map(line => line.split(","))
    case class CC1(LAT: Double, LONG: Double)
    val allData = allSplit.map( p => CC1( p(0).trim.toDouble, p(1).trim.toDouble))
    val allDF = allData.toDF()
    // ... other code
  }

}

错误如下:

  

错误:(40,25)值toDF不是org.apache.spark.rdd.RDD [CC1]的成员       val allDF = allData.toDF()

2 个答案:

答案 0 :(得分:1)

在主方法中定义案例类CC1 时,您点击了https://issues.scala-lang.org/browse/SI-6649; toDF()然后无法在编译时为该类找到适当的隐式TypeTag

你可以在这个简单的例子中看到这一点:

case class Out()

object TestImplicits {

  def main(args: Array[String]) {
    case class In()
    val typeTagOut = implicitly[TypeTag[Out]] // compiles
    val typeTagIn = implicitly[TypeTag[In]]   // does not compile: Error:(23, 31) No TypeTag available for In
  }

}

Spark的相关隐式转换具有以下类型参数:[T <: Product : TypeTag](请参阅newProductEncoder here),这意味着需要隐式TypeTag[CC1]

要解决此问题 - 只需将CC1的定义移出方法,或完全移出对象:

case class CC1(LAT: Double, LONG: Double)

object spark1 {

  def main(args: Array[String]) {
    val spark = SparkSession.builder().appName("e1").config("o1", "sv").getOrCreate()

    import spark.implicits._

    val data = spark.sparkContext.textFile("/TestDataB.txt")
    val allSplit = data.map(line => line.split(","))

    val allData = allSplit.map( p => CC1( p(0).trim.toDouble, p(1).trim.toDouble))
    val allDF = allData.toDF()
    // ... other code
  }

}

答案 1 :(得分:0)

我认为Franchise位于toDF,因此您需要导入sqlContext.implicits._。至少在spark 1.6

中就是这种情况