Преобразование фрейма данных в хэш-карту с помощью Spark Scala

#scala #apache-spark #apache-spark-sql

#scala #apache-spark #apache-spark-sql

Вопрос:

Мой фрейм данных выглядит так:

  ------------------- ------------- 
|        Nationality|    continent|
 ------------------- ------------- 
|       Turkmenistan|         Asia|
|         Azerbaijan|         Asia|
|             Canada|North America|
|         Luxembourg|       Europe|
|             Gambia|       Africa|
  

Мой вывод должен выглядеть следующим образом:

 Map(Gibraltar -> Europe, Haiti -> North America)
  

Итак, я пытаюсь преобразовать фрейм данных в

 scala.collection.mutable.Map[String, String]()
  

Я пытаюсь использовать следующий код:

     var encoder = Encoders.product[(String, String)]
    val countryToContinent = scala.collection.mutable.Map[String, String]()
    var mapped = nationalityDF.mapPartitions((it) => {
        ....
        ....
        countryToContinent.toIterator
    })(encoder).toDF("Nationality", "continent").as[(String, String)](encoder)

    val map = mapped.rdd.groupByKey.collect.toMap
  

Но результирующая карта имеет следующий вывод:

 Map(Gibraltar -> CompactBuffer(Europe), Haiti -> CompactBuffer(North America))
  

Как я могу получить результат хэш-карты без CompactBuffer?

Ответ №1:

Давайте создадим некоторые данные:

 val df = Seq(
("Turkmenistan", "Asia"), 
("Azerbaijan", "Asia"))
.toDF("Country", "Continent")
  

Сначала попробуйте отобразить в кортеж, а затем собрать в карту:

 df.map{ r => (r.getString(0), r.getString(1))}.collect.toMap
  

Вывод:

 scala.collection.immutable.Map[String,String] = Map(Turkmenistan -> Asia, Azerbaijan -> Asia)
  

Комментарии:

1. Спасибо. он работает нормально.. Я только что добавил кодировщик на карту :: newDF.map{ r => (r.getString(0), r.getString(1))}(encoder).collect.toMap

2. Привет @Hanan почему вы явно добавили кодировщик? В этом случае я не думаю, что вам нужно устанавливать кодировщик. Я бы не стал связываться с кодировщиками, если в этом нет необходимости 🙂 т.е. Spark не может распознать кодировку моего пользовательского типа! здесь вы можете найти хорошее объяснение о кодировщиках github.com/vaquarkhan/Apache-Kafka-poc-and-notes/wiki /…

3. На самом деле это выдало ошибку до того, как я добавил кодировщик: Ошибка: (58, 34) недостаточно аргументов для метода map: (неявное доказательство $ 6: org.apache.spark.sql.Encoder[(Строка, строка)])org.apache.spark.sql.Dataset[(Строка, строка)])Строка)]. Неопределенное значение параметра свидетельствует о $ 6. countryToContinent = newDF.map { r => (r.getString(0), r.getString(1)) }.collect.toMap

4. правильно, я вижу, тогда вы должны полностью удалить кодировщик! Вам это действительно не нужно. Просто импортируйте spark.implicits. _ должно быть достаточно

5. Большое спасибо! да, ты прав… он отлично работает с использованием spark.implicits._