为什么以下失败?
val fd:Dataset[Map[Int, Int]] = Seq(Map(1->2, 3->4), Map(5->6), Map(8->9)).toDS()
error: value toDS is not a member of Seq[scala.collection.immutable.Map[Int,Int]]
虽然这有效:
val cd:Dataset[Array[Int]] = Seq(Array(1, 2, 3), Array(100)).toDS()
cd: org.apache.spark.sql.Dataset[Array[Int]] = [value: array<int>]
答案 0 :(得分:4)
这是因为SQLImplicits Map编码器仅在Spark 2.3.0中添加。 升级到2.3.0并开始工作。
// Maps
/** @since 2.3.0 */
implicit def newMapEncoder[T <: Map[_, _] : TypeTag]: Encoder[T] = ExpressionEncoder()
答案 1 :(得分:3)
如果你可以升级到Spark 2.3 - 它可能是Traian建议的最好的主意。 Spark 2.0(在2.0.2上测试)可以使用变通方法:
1)将Map
转换为Seq
:
scala> val seq2 = Seq(Map(1->2, 3->4), Map(5->6), Map(8->9)).map(_.toSeq)
seq2: Seq[Seq[(Int, Int)]] = List(ArrayBuffer((1,2), (3,4)), ArrayBuffer((5,6)), ArrayBuffer((8,9)))
scala> val ds = seq2.toDS()
ds: org.apache.spark.sql.Dataset[Seq[(Int, Int)]] = [value: array<struct<_1:int,_2:int>>]
scala> ds.printSchema()
root
|-- value: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- _1: integer (nullable = false)
| | |-- _2: integer (nullable = false)
scala> ds.collect().foreach(println)
WrappedArray((1,2), (3,4))
WrappedArray((5,6))
WrappedArray((8,9))
2)用案例类包装成struct
(注意我必须在Spark 2.0的案例类定义中使用scala.collection.Map
,因为另一个应该在2.1 / 2.2分支中修复的bug https://issues.apache.org/jira/browse/SPARK-18717)
scala> case class WrapMap[K, V](m: scala.collection.Map[K, V])
defined class WrapMap
scala> val seq3 = Seq(Map(1->2, 3->4), Map(5->6), Map(8->9)).map(WrapMap(_))
seq3: Seq[WrapMap[Int,Int]] = List(WrapMap(Map(1 -> 2, 3 -> 4)), WrapMap(Map(5 -> 6)), WrapMap(Map(8 -> 9)))
scala> val ds = seq3.toDS()
ds: org.apache.spark.sql.Dataset[WrapMap[Int,Int]] = [m: map<int,int>]
scala> ds.collect().foreach(println)
WrapMap(Map(1 -> 2, 3 -> 4))
WrapMap(Map(5 -> 6))
WrapMap(Map(8 -> 9))
答案 2 :(得分:0)
您可以使用zipWithIndex
,然后Map
Dataset
创建{。}}。
val fd: Dataset[Map[Int, Int]] =
Seq(Map(1->2, 3->4), Map(5->6), Map(8->9)).zipWithIndex.toDS().map(_._1)