15

我见过各种各样的人暗示Dataframe.explode是实现此目的的一种有用方法,但它会产生比原始数据帧更多的行,这不是我想要的。我只想做数据框相当于非常简单的:将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 

我不知道我怎么会在一般情况下,解决这个问题,其中Row to Row中嵌套数组的大小不一样。

+0

您是否找到了针对一般不均匀情况的解决方案? –

+0

不幸的是我从来没有。 –

+2

结束了使用python循环,即 - 对于我在范围内(最大(len_of_split):df = df.withcolumn(split.getItem(i)) –