15

Я видел разных людей, предлагающих, что Dataframe.explode - полезный способ сделать это, но в результате получается больше строк, чем исходный фреймворк, что совсем не то, что я хочу. Я просто хочу, чтобы сделать Dataframe эквивалент очень прост:Разделите колонку строки данных Split Spark на несколько столбцов

rdd.map(lambda row: row + [row.my_str_col.split('-')]) 

который принимает что-то выглядит как:

col1 | my_str_col 
-----+----------- 
    18 | 856-yygrm 
201 | 777-psgdg 

и преобразует его к этому:

col1 | my_str_col | _col3 | _col4 
-----+------------+-------+------ 
    18 | 856-yygrm | 856 | yygrm 
201 | 777-psgdg | 777 | psgdg 

Я знаю pyspark.sql.functions.split(), но это приводит к столбцу вложенного массива вместо двух столбцов верхнего уровня, как я хочу.

В идеале я хочу, чтобы эти новые столбцы также были названы.

ответ

26

pyspark.sql.functions.split() - правильный подход здесь - вам просто нужно сгладить вложенный столбец ArrayType на несколько столбцов верхнего уровня. В этом случае, когда каждый массив содержит только 2 элемента, это очень просто. Вы просто использовать Column.getItem(), чтобы получить каждую часть массива в качестве самого столбца:

split_col = pyspark.sql.functions.split(df['my_str_col'], '-') 
df = df.withColumn('NAME1', split_col.getItem(0)) 
df = df.withColumn('NAME2', split_col.getItem(1)) 

Результат будет:

col1 | my_str_col | NAME1 | NAME2 
-----+------------+-------+------ 
    18 | 856-yygrm | 856 | yygrm 
201 | 777-psgdg | 777 | psgdg 

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

+0

Вы нашли решение для общего неравномерного случая? –

+0

К сожалению, я так и не сделал. –

+2

закончил использование цикла python, то есть - для i в диапазоне (max (len_of_split): df = df.withcolumn (split.getItem (i)) –