【问题标题】:Compilation Encoder error on spark 2.0spark 2.0 上的编译编码器错误
【发布时间】:2017-06-11 16:46:37
【问题描述】:

我正在尝试从 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 等)和产品类型(案例类)。未来版本中将添加对序列化其他类型的支持。 val subGroupCount: Array[Seq[Any]] = columns.map(c => df.select(c).distinct.map(x => x.get(0)).collect.toSeq)

问候

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:

    方法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)
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-26
      • 2010-10-01
      • 2010-11-10
      • 2021-03-21
      • 1970-01-01
      • 2015-09-13
      • 2017-04-19
      • 2018-02-01
      相关资源
      最近更新 更多