Боковой вид / взрыв в Spark с несколькими столбцами, получение дубликатов - PullRequest
1 голос
/ 21 мая 2019

У меня есть следующий фрейм данных с некоторыми столбцами, которые содержат массивы. (Мы используем спарк 1.6)

+--------------------+--------------+------------------+--------------+--------------------+-------------+
|            UserName|     col1     |    col2          |col3          |col4                |col5         |
+--------------------+--------------+------------------+--------------+--------------------+-------------+
|foo                 |[Main, Indi...|[1777203, 1777203]|    [GBP, GBP]|            [CR, CR]|   [143, 143]|
+--------------------+--------------+------------------+--------------+--------------------+-------------+

И я ожидаю следующий результат:

+--------------------+--------------+------------------+--------------+--------------------+-------------+
|            UserName|     explod   |    explod2       |explod3       |explod4             |explod5      |
+--------------------+--------------+------------------+--------------+--------------------+-------------+
|NNNNNNNNNNNNNNNNN...|      Main    |1777203           |    GBP      |     CR              |    143      |
|NNNNNNNNNNNNNNNNN...|Individual    |1777203           |    GBP      |     CR              |    143      |
----------------------------------------------------------------------------------------------------------

Я пробовал боковое представление:

sqlContext.sql("SELECT `UserName`, explod, explod2, explod3, explod4, explod5 FROM sourceDF
LATERAL VIEW explode(`col1`) sourceDF AS explod 
LATERAL VIEW explode(`col2`) explod AS explod2 
LATERAL VIEW explode(`col3`) explod2 AS explod3 
LATERAL VIEW explode(`col4`) explod3 AS explod4 
LATERAL VIEW explode(`col5`) explod4 AS explod5")

Но я получаю декартово произведение с большим количеством дубликатов. Я попробовал то же самое, взорвав все столбцы с помощью метода ccolumn, но все еще получаю много дубликатов

.withColumn("col1", explode($"col1"))...

Конечно, я могу сделать отличный от окончательного кадра данных, но это не элегантное решение. Есть ли способ взорвать столбцы без получения всех этих дубликатов?

Спасибо!

1 Ответ

2 голосов
/ 21 мая 2019

Если вы используете Spark 2.4.0 или новее, arrays_zip облегчает задачу

val df = Seq(
  ("foo",
   Seq("Main", "Individual"),
   Seq(1777203, 1777203),
   Seq("GBP", "GBP"),
   Seq("CR", "CR"),
   Seq(143, 143)))
  .toDF("UserName", "col1", "col2", "col3", "col4", "col5")

df.select($"UserName",
          explode(arrays_zip($"col1", $"col2", $"col3", $"col4", $"col5")))
  .select($"UserName", $"col.*")
  .show()

Выход:

+--------+----------+-------+----+----+----+
|UserName|      col1|   col2|col3|col4|col5|
+--------+----------+-------+----+----+----+
|     foo|      Main|1777203| GBP|  CR| 143|
|     foo|Individual|1777203| GBP|  CR| 143|
+--------+----------+-------+----+----+----+
...