Как разбить два поля массива на несколько столбцов в Spark? - PullRequest
0 голосов
/ 19 сентября 2018

Я имел в виду Как разбить массив на несколько столбцов в Spark для аналогичной необходимости.

Я могу использовать этот код для одного фрейма данных поля массива, однако, когда у меня есть фрейм данных с несколькими полями массива, я не могу конвертировать оба в несколько столбцов.

ДляНапример,

dataframe1

+--------------------+----------------------------------+----------------------------------+
|                 f1 |f2                                |f3                                |
+--------------------+----------------------------------+----------------------------------+
|12                  |                              null|                              null|
|13                  |                              null|                              null|
|14                  |                              null|                              null|
|15                  |                              null|                              null|
|16                  |                              null|                              null|
|17                  |                [[Hi, 256, Hello]]|        [[a, b], [a, b, c],[a, b]]|
|18                  |                              null|                              null|
|19                  |                              null|                              null|
+--------------------+----------------------------------+----------------------------------+

Я хочу преобразовать его в приведенный ниже фрейм данных:

dataframe2

+--------------------+----------------------------------+----------------------------------+----------------------------------+
|                 f1 |f2_0                              |f3_0                              |f3_1                              |
+--------------------+----------------------------------+----------------------------------+----------------------------------+
|12                  |                              null|                              null|                              null|
|13                  |                              null|                              null|                              null|
|14                  |                              null|                              null|                              null|
|15                  |                              null|                              null|                              null|
|16                  |                              null|                              null|                              null|
|17                  |                  [Hi, 256, Hello]|                            [a, b]|                         [a, b, c]|
|18                  |                              null|                              null|                              null|
|19                  |                              null|                              null|                              null|
+--------------------+----------------------------------+----------------------------------+----------------------------------+

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

val dataframe2 = dataframe1.select(
  col("f1") +: (0 until 2).map(i => col("f2")(i).alias(s"f2_$i")): _* +: (0 until 2).map(i => col("f3")(i).alias(s"f3_$i")): _*
)

Но выдает ошибку, говорящую, что он ожидает ")" после первого "_ *".

Ответы [ 2 ]

0 голосов
/ 20 сентября 2018

Ответ Шайдо уже верен, и этот ответ является лишь дополнением к этому.Здесь я только что добавил, чтобы найти максимальную длину столбцов динамически.

Если столбец f2 и f3 уже массив, то соответствующие максимальные размеры массива вычисляются, как показано ниже.

val s1 = df.select(max(size(df("f2")))).first().getInt(0)
val s2 = df.select(max(size(df("f3")))).first().getInt(0)

Иначе, если столбец должен быть разбит на основе разделителя и далее разделен на столбцы, сначала вычисляя размер, как показано ниже.

val s1 = df.select(max(size(split(df("f2"), ",")))).first().getInt(0)
val s2 = df.select(max(size(split(df("f3"), ",")))).first().getInt(0)

И тогда мы можем использовать s1, s2 в функции карты в ответе Шайдо как (0 until s1).map( .....

0 голосов
/ 19 сентября 2018

+: используется в Scala для добавления одного элемента в список.Его нельзя использовать для объединения двух списков.Вместо этого вы можете использовать ++ следующим образом:

val cols = Seq(col("f1")) 
  ++ (0 until 1).map(i => col("f2")(i).alias(s"f2_$i")) 
  ++ (0 until 2).map(i => col("f3")(i).alias(s"f3_$i"))

val dataframe2 = dataframe1.select(cols: _*)

Обратите внимание, что для использования этого подхода вам необходимо заранее знать количество элементов списков.Выше я изменил 2 на 1 для столбца f2.

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