Pyspark:将多个数组列拆分为行

我有一个具有一行和几列的数据框。一些列是单个值,另一些是列表。所有列表列的长度均相同。我想将每个列表列拆分为单独的行,同时将任何非列表列保持原样。


样本DF:


from pyspark import Row

from pyspark.sql import SQLContext

from pyspark.sql.functions import explode


sqlc = SQLContext(sc)


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()


动漫人物
浏览 1345回答 3
3回答

慕的地10843

您需要使用flatMap,而不是map要在每个输入行中创建多个输出行。from pyspark.sql import Rowdef dualExplode(r):    rowDict = r.asDict()    bList = rowDict.pop('b')    cList = rowDict.pop('c')    for b,c in zip(bList, cList):        newDict = dict(rowDict)        newDict['b'] = b        newDict['c'] = c        yield Row(**newDict)df_split = sqlContext.createDataFrame(df.rdd.flatMap(dualExplode))

FFIVE

zip将obj的第一个元素与另一个对象的第一个元素,第2个和第2个元素等配对在一起,直到其中一个对象用完元素。您的情况是2个值之后。换句话说,它将配对元素,直到没有更多要配对的项目为止。要提出任何建议,我需要知道您希望程序如何处理未配对的元素(例如,您是否要从第二组中获取空值?)。同样,在此示例中只有1 df。如果你的问题是从这一不同,它可能会更好,只是问了另一个问题
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python