spark 2.0上的编译编码器错误

时间:2017-01-26 08:45:08

标签: scala apache-spark

我正在尝试从spark 1.6移动到2.0,我只在2.0编译时遇到此错误:

def getSubGroupCount(df: DataFrame, colNames: String): Array[Seq[Any]] = {
   val columns: Array[String] = colNames.split(',')
   val subGroupCount: Array[Seq[Any]] = columns.map(c => df.select(c).distinct.map(x => x.get(0)).collect.toSeq)
    subGroupCount
  }
  

无法找到存储在数据集中的类型的编码器。导入spark.implicits支持原始类型(Int,String等)和产品类型(case类)。在将来的版本中将添加对序列化其他类型的支持。   val subGroupCount:Array [Seq [Any]] = columns.map(c => df.select(c).distinct.map(x => x.get(0))。collect.toSeq)

此致

1 个答案:

答案 0 :(得分:0)

方法DataFrame.map在版本之间发生了变化:

  • 在Spark 1.6中,它对基础RDD[Row]进行操作并返回RDD

    def map[R](f: (Row) ⇒ R)(implicit arg0: ClassTag[R]): RDD[R]
    
  • 在Spark 2.0中,DataFrame只是Dataset[Row]的别名,因此会返回Dataset

    def map[U](func: (T) ⇒ U)(implicit arg0: Encoder[U]): Dataset[U] 
    

如您所见,后者需要一个隐含的Encoder参数,在您的情况下缺少该参数。

为什么缺少编码器

首先,导入spark.implicits._后,所有默认编码器都在范围内。但是,由于映射的结果类型为Anyx => x.get(0)返回Any),因此您将无法使用编码器。

如何解决此问题?

  1. 如果您感兴趣的所有列都有一个共同类型(例如,String,为了示例),您可以使用getAs[String](0)使映射函数返回特定类型。添加上述导入后,此类型(基元,产品)将在范围内具有匹配的编码器

  2. 如果您没有所有相关列通用的已知类型,并希望保留相同的行为 - 您可以使用RDD获取Dataframe的.rdd并使用RDD的map操作,与2.0之前的行为相同:

    columns.map(c => df.select(c).distinct.rdd.map(x => x.get(0)).collect.toSeq)