получить доступ к карте scala из фрейма данных без использования пользовательских функций - PullRequest
0 голосов
/ 18 мая 2018

У меня есть Spark (версия 1.6) Dataframe, и я хотел бы добавить столбец со значением, содержащимся в Scala Map, это мой упрощенный код:

val map = Map("VAL1" -> 1, "VAL2" -> 2)
val df2 = df.withColumn("newVal", map(col("key")))

Этот код нене работает, и, очевидно, я получаю следующую ошибку, потому что карта ожидает значение String при получении столбца:

found   : org.apache.spark.sql.Column
required: String

Единственный способ, которым я мог бы сделать это, - использовать UDF:

val map = Map("VAL1" -> 1, "VAL2" -> 2)
val myUdf = udf{ value:String => map(value)}
val df2 = df.withColumn("newVal", myUdf($"key"))

Я хочу по возможности избегать использования UDF.

Существуют ли другие доступные решения, использующие только API DataFrame (я также хотел бы избежать преобразования его в RDD)?

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Вы можете преобразовать карту в Dataframe и использовать JOIN между этим и вашим существующим DataFrame.Поскольку информационный фрейм карты будет очень маленьким, это должно быть широковещательное соединение и избегать необходимости в фазе тасования.

В этом ответе описывается, как Spark узнает об использовании широковещательного соединения: Оптимизация соединения в DataFrame- Broadcast Hash Join

0 голосов
/ 18 мая 2018

TL; DR Просто используйте udf.

С версией, которую вы используете (Spark 1.6 согласно вашему комментарию), не существует решения, которое не требует udf илиmap более RDD / Dataset.

В более поздних версиях вы можете:

  • использовать функции map (2.0 или более поздние) для создания литерала MapType столбец

    import org.apache.spark.sql.functions
    
    val map = functions.map(
       Map("VAL1" -> 1, "VAL2" -> 2)
         .flatMap { case (k, v) =>  Seq(k, v) } .map(lit) .toSeq: _*
    )
    map($"key")
    
  • typedLit (2,2 или более поздней версии) для создания литерального столбца MapType.

    val map = functions.typedLit(Map("VAL1" -> 1, "VAL2" -> 2))
    map($"key")
    

ииспользуйте их напрямую.

Ссылка Как добавить постоянный столбец в кадре данных Spark?

...