我正在尝试从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)
此致
答案 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._
后,所有默认编码器都在范围内。但是,由于映射的结果类型为Any
(x => x.get(0)
返回Any
),因此您将无法使用编码器。
如何解决此问题?
如果您感兴趣的所有列都有一个共同类型(例如,String
,为了示例),您可以使用getAs[String](0)
使映射函数返回特定类型。添加上述导入后,此类型(基元,产品)将在范围内具有匹配的编码器
如果您没有所有相关列通用的已知类型,并希望保留相同的行为 - 您可以使用RDD
获取Dataframe的.rdd
并使用RDD的map
操作,与2.0之前的行为相同:
columns.map(c => df.select(c).distinct.rdd.map(x => x.get(0)).collect.toSeq)