簡體   English   中英

如何從一系列地圖創建數據集?

[英]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,它將開始工作。

https://github.com/apache/spark/blob/master/sql/core/src/main/scala/org/apache/spark/sql/SQLImplicits.scala#L170-L172

// 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM