복붙노트

[SCALA] SparkSQL DataFrame에지도 유형 열에서 키와 값을 얻는 방법

SCALA

SparkSQL DataFrame에지도 유형 열에서 키와 값을 얻는 방법

것으로, object_id : 문자열 및 알파 :지도 <> 나는 마루 2 개 필드가 파일에 데이터를 가지고있다.

그것은 스파크 SQL과 같은 스키마 외모에 dataframe로 읽어 :

scala> alphaDF.printSchema()
root
 |-- object_id: string (nullable = true)
 |-- ALPHA: map (nullable = true)
 |    |-- key: string
 |    |-- value: struct (valueContainsNull = true)

나는 스파크 2.0를 사용하고 난 열 OBJECT_ID, 키 1, 키 2, 키 2에서와 알파 맵의 플러스 키 OBJECT_ID 할 필요가있는 새로운 데이터 프레임을 만들려고하고 있어요 ...

나는 처음에는 이상 접속이 같은지도를 할 수 있는지 확인하기 위해 노력했다 :

scala> alphaDF.map(a => a(0)).collect()
<console>:32: 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.
   alphaDF.map(a => a(0)).collect()

하지만 불행히도 나는지도의 키에 액세스하는 방법을 알아낼 수있을 수없는 것.

누군가가 OBJECT_ID를 얻을 플러스 열 이름으로 키를 매핑하고 새로운 dataframe에서 각각의 값과 같은 값을 매핑하는 저에게 방법을 보여 주시겠습니까?

해결법

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

    1.스파크> = 2.3

    스파크> = 2.3

    당신은 map_keys 기능을 사용하여 프로세스를 단순화 할 수 있습니다 :

    import org.apache.spark.sql.functions.map_keys
    

    이 map_values ​​기능은, 그러나 여기에 직접 도움이되지 않습니다.

    스파크 <2.3

    일반적인 방법은 몇 단계로 표현 될 수있다. 먼저 수입을 필요 :

    import org.apache.spark.sql.functions.udf
    import org.apache.spark.sql.Row
    

    예컨대 데이터 :

    val ds = Seq(
      (1, Map("foo" -> (1, "a"), "bar" -> (2, "b"))),
      (2, Map("foo" -> (3, "c"))),
      (3, Map("bar" -> (4, "d")))
    ).toDF("id", "alpha")
    

    추출 키에 우리는 UDF (스파크를 <2.3)을 사용할 수 있습니다

    val map_keys = udf[Seq[String], Map[String, Row]](_.keys.toSeq)
    

    또는 내장 함수

    import org.apache.spark.sql.functions.map_keys
    
    val keysDF = df.select(map_keys($"alpha"))
    

    별개의 사람 찾기 :

    val distinctKeys = keysDF.as[Seq[String]].flatMap(identity).distinct
      .collect.sorted
    

    또한 폭발과 함께 키 추출을 일반화 할 수 있습니다 :

    import org.apache.spark.sql.functions.explode
    
    val distinctKeys = df
      // Flatten the column into key, value columns
     .select(explode($"alpha"))
     .select($"key")
     .as[String].distinct
     .collect.sorted
    

    그리고 선택 :

    ds.select($"id" +: distinctKeys.map(x => $"alpha".getItem(x).alias(x)): _*)
    
  2. ==============================

    2.당신이 PySpark에있는 경우에, 난 그냥 쉽게 구현을 찾을 수 있습니다 :

    당신이 PySpark에있는 경우에, 난 그냥 쉽게 구현을 찾을 수 있습니다 :

    from pyspark.sql.functions import map_keys
    
    alphaDF.select(map_keys("ALPHA").alias("keys")).show()
    

    당신은 여기에서 자세한 내용을 확인할 수 있습니다

  3. from https://stackoverflow.com/questions/40602606/how-to-get-keys-and-values-from-maptype-column-in-sparksql-dataframe by cc-by-sa and MIT license