У меня есть dataframe, который имеет одну строку и несколько столбцов. Некоторые из столбцов являются одиночными значениями, а другие - списками. Все столбцы списка имеют одинаковую длину. Я хочу разбить каждый столбец списка на отдельную строку, сохраняя любой столбец без списка, как есть.
Пример DF:
df = sqlc.createDataFrame([Row(a=1, b=[1,2,3],c=[7,8,9], d='foo')])
# +---+---------+---------+---+
# | a| b| c| d|
# +---+---------+---------+---+
# | 1|[1, 2, 3]|[7, 8, 9]|foo|
# +---+---------+---------+---+
Что я хочу:
+---+---+----+------+
| a| b| c | d |
+---+---+----+------+
| 1| 1| 7 | foo |
| 1| 2| 8 | foo |
| 1| 3| 9 | foo |
+---+---+----+------+
Если бы у меня был только один столбец списка, это было бы легко, просто сделав explode
:
df_exploded = df.withColumn('b', explode('b'))
# >>> df_exploded.show()
# +---+---+---------+---+
# | a| b| c| d|
# +---+---+---------+---+
# | 1| 1|[7, 8, 9]|foo|
# | 1| 2|[7, 8, 9]|foo|
# | 1| 3|[7, 8, 9]|foo|
# +---+---+---------+---+
Однако, если я попытаюсь также explode
столбец c
, я получаю данные с длиной, квадратом которой я хочу:
df_exploded_again = df_exploded.withColumn('c', explode('c'))
# >>> df_exploded_again.show()
# +---+---+---+---+
# | a| b| c| d|
# +---+---+---+---+
# | 1| 1| 7|foo|
# | 1| 1| 8|foo|
# | 1| 1| 9|foo|
# | 1| 2| 7|foo|
# | 1| 2| 8|foo|
# | 1| 2| 9|foo|
# | 1| 3| 7|foo|
# | 1| 3| 8|foo|
# | 1| 3| 9|foo|
# +---+---+---+---+
Что я хочу - для каждого столбца возьмите n-й элемент массива в этом столбце и добавьте его в новую строку. Я пробовал сопоставлять разнесение по всем столбцам в фреймворке данных, но это тоже не работает:
df_split = df.rdd.map(lambda col: df.withColumn(col, explode(col))).toDF()