Как преобразовать массивы в карту? - PullRequest
0 голосов
/ 11 июня 2019

У меня есть такой искровой фрейм данных: enter image description here

Схема: enter image description here Я хочу получить конечный результат, подобный этому: enter image description here А именно, для создания карты между _1: integer и _2: map в site_group.

Как это сделать в Scala Spark?

1 Ответ

1 голос
/ 11 июня 2019

Вот одно из решений. Сначала давайте создадим некоторые примерные данные, аналогичные вашим. Между прочим, было бы гораздо полезнее опубликовать вопрос с воспроизводимыми данными ввода и вывода, как обсуждено здесь .

val df = Seq(
(999, "2019-05-23", Seq((0,Map(2154 -> 0.545)))),
(511, "2019-06-30", Seq((1,Map(564654 -> 0.255699)))),
(322, "2019-02-10", Seq((2,Map(122 -> 0.896)))))
.toDF("user_id","dt", "site_group_collect")

// +-------+----------+---------------------------+
// |user_id|dt        |site_group_collect         |
// +-------+----------+---------------------------+
// |999    |2019-05-23|[[0, [2154 -> 0.545]]]     |
// |511    |2019-06-30|[[1, [564654 -> 0.255699]]]|
// |322    |2019-02-10|[[2, [122 -> 0.896]]]      |
// +-------+----------+---------------------------+

Затем мы перебираем каждый элемент и преобразуем значения site_group_collect, используя функцию map кадра данных:

df.map{case Row(uid: Int, dt: String, group: Seq[Row]) => 
     val transformed = group.map{ r => Map(r.getInt(0) -> r.get(1).asInstanceOf[Map[Int, Double]]) }
     (uid, dt, transformed)
}
.toDF("user_id","dt", "site_group_collect")
.show(false)

// +-------+----------+-----------------------------+
// |user_id|dt        |site_group_collect           |
// +-------+----------+-----------------------------+
// |999    |2019-05-23|[[0 -> [2154 -> 0.545]]]     |
// |511    |2019-06-30|[[1 -> [564654 -> 0.255699]]]|
// |322    |2019-02-10|[[2 -> [122 -> 0.896]]]      |
// +-------+----------+-----------------------------+

Ключевым моментом здесь является представление массива кортежей [[0, [2154 -> 0.545]]] в виде массива Row с. Другой подход заключается в представлении кортежа как case class, т.е.:

case class Item(pk: Int, m: Map[Int, Double])

Строка:

val transformed = group.map{ r => Map(r.getInt(0) -> r.get(1).asInstanceOf[Map[Int, Double]]) }

Извлечет комбинацию key/value из существующего кортежа и назначит ее вновь созданному Map.

Некоторые похожие посты:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...