복붙노트

[SCALA] 어떻게지도의 데이터 집합을 만드는 방법?

SCALA

어떻게지도의 데이터 집합을 만드는 방법?

나는 스파크 2.2을 사용하고 있는데지도의 서열에 spark.createDataset를 호출 할 때 문제로 실행하고 있습니다.

코드 내 스파크 셸 세션 추적 출력 :

// createDataSet on Seq[T] where T = Int works
scala> spark.createDataset(Seq(1, 2, 3)).collect
res0: Array[Int] = Array(1, 2, 3)

scala> spark.createDataset(Seq(Map(1 -> 2))).collect
<console>:24: error: Unable to find encoder for type stored in a Dataset.  
Primitive types (Int, String, etc) and Product types (case classes) are 
supported by importing spark.implicits._
Support for serializing other types will be added in future releases.
       spark.createDataset(Seq(Map(1 -> 2))).collect
                          ^

// createDataSet on a custom case class containing Map works
scala> case class MapHolder(m: Map[Int, Int])
defined class MapHolder

scala> spark.createDataset(Seq(MapHolder(Map(1 -> 2)))).collect
res2: Array[MapHolder] = Array(MapHolder(Map(1 -> 2)))

나는의 암시 적 스파크 쉘 세션에 의해 수입 된 것을 매우 확신하지만 나는, 수입 spark.implicits._을 시도했습니다.

이것은 현재 인코더에 포함되지 않은 경우가 있습니까?

해결법

  1. ==============================

    1.그것은 2.2에 포함되지 않고, 쉽게 해결 될 수 있습니다. 당신은 명시 적으로, ExpressionEncoder을 사용하는 인코더가 필요 추가 할 수 있습니다 :

    그것은 2.2에 포함되지 않고, 쉽게 해결 될 수 있습니다. 당신은 명시 적으로, ExpressionEncoder을 사용하는 인코더가 필요 추가 할 수 있습니다 :

    import org.apache.spark.sql.catalyst.encoders.ExpressionEncoder  
    import org.apache.spark.sql.Encoder
    
    spark
      .createDataset(Seq(Map(1 -> 2)))(ExpressionEncoder(): Encoder[Map[Int, Int]])
    

    또는 암시 :

    implicit def mapIntIntEncoder: Encoder[Map[Int, Int]] = ExpressionEncoder()
    spark.createDataset(Seq(Map(1 -> 2)))
    
  2. ==============================

    2.그냥 참고로 위의 표현은 단지 스파크 2.3에서 작동 (내가 잘못 아니에요 경우이의 확약).

    그냥 참고로 위의 표현은 단지 스파크 2.3에서 작동 (내가 잘못 아니에요 경우이의 확약).

    scala> spark.version
    res0: String = 2.3.0
    
    scala> spark.createDataset(Seq(Map(1 -> 2))).collect
    res1: Array[scala.collection.immutable.Map[Int,Int]] = Array(Map(1 -> 2))
    

    나는 newMapEncoder 지금 spark.implicits의 일부이기 때문에 그것은 생각합니다.

    scala> :implicits
    ...
      implicit def newMapEncoder[T <: scala.collection.Map[_, _]](implicit evidence$3: reflect.runtime.universe.TypeTag[T]): org.apache.spark.sql.Encoder[T]
    

    당신은 "사용 안 함"다음 트릭을 사용하여 위의 표현 시도해에 의해 암시 적 (즉 오류로 이어질 것) 할 수있다.

    trait ThatWasABadIdea
    implicit def newMapEncoder(ack: ThatWasABadIdea) = ack
    
    scala> spark.createDataset(Seq(Map(1 -> 2))).collect
    <console>:26: error: Unable to find encoder for type stored in a Dataset.  Primitive types (Int, String, etc) and Product types (case classes) are supported by importing spark.implicits._  Support for serializing other types will be added in future releases.
           spark.createDataset(Seq(Map(1 -> 2))).collect
                              ^
    
  3. from https://stackoverflow.com/questions/46778659/how-to-create-a-dataset-of-maps by cc-by-sa and MIT license