[英]How to create a Dataset from a sequence of maps?
為什么以下失敗?
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>]
這是因為SQLImplicits Map編碼器僅在Spark 2.3.0中添加。 升級到2.3.0,它將開始工作。
// Maps
/** @since 2.3.0 */
implicit def newMapEncoder[T <: Map[_, _] : TypeTag]: Encoder[T] = ExpressionEncoder()
如果您可以升級到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
(請注意,由於另一個應在2.1 / 2.2分支中修復的錯誤,我必須在Spark 2.0的案例類定義中使用scala.collection.Map
://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))
您可以使用zipWithIndex
,然后使用Map
post創建Dataset
。
val fd: Dataset[Map[Int, Int]] =
Seq(Map(1->2, 3->4), Map(5->6), Map(8->9)).zipWithIndex.toDS().map(_._1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.