Pyspark - 将多列数据组合成跨行分布的单列[重复]

Posted

技术标签:

【中文标题】Pyspark - 将多列数据组合成跨行分布的单列[重复]【英文标题】:Pyspark - Combine Multiple Columns of Data into a Single Column Spread Out Across Rows [duplicate] 【发布时间】:2020-02-06 18:07:28 【问题描述】:

我有一个包含多个列的 pyspark 数据框,如下所示:

name    col1    col2    col3
A        1        6       7
B        2        7       6
C        3        8       5
D        4        9       4
E        5        8       3

我想在 pyspark 中创建一个新的数据框,方法是将 col1、col2、col3 的列名和列值组合成两个新列,例如,new_col 和 new_col_val,跨行分布:

我使用以下代码在 R 中做了同样的事情:

df1 <- gather(df,new_col,new_col_val,-name)

我想创建 3 个单独的数据帧,它们将包含原始数据帧中的每一列,然后将它们附加在一起,但我的数据有超过 2500k 行和大约 60 列。创建多个数据框将是最糟糕的主意。 谁能告诉我如何在 pyspark 中执行此操作?

【问题讨论】:

melt 是 pyspark 中的一个选项吗? pyspark 中没有像 melt 这样的功能,但是通过这个链接***.com/questions/41670103/… 我可以解决这个问题。谢谢你给我一个使用melt的想法:) 你可以参考类似问题的答案codereview.stackexchange.com/questions/200391/… 【参考方案1】:

您可以使用unionAll将列转换为行,lit可以用于指定列名,如下所示,

from pyspark.sql.functions import lit

df2 = df.select(df.columns[0], lit(df.columns[1]).alias('new_col'),
                df[df.columns[1]].alias('new_col_val'))

for i in df.columns[2:]:
    df2 = df2.unionAll(df.select(df.columns[0], lit(i), df[i]))

输出:

+----+-------+-----------+
|name|new_col|new_col_val|
+----+-------+-----------+
|   A|   col1|          1|
|   B|   col1|          2|
|   C|   col1|          3|
|   D|   col1|          4|
|   E|   col1|          5|
|   A|   col2|          6|
|   B|   col2|          7|
|   C|   col2|          8|
|   D|   col2|          9|
|   E|   col2|          8|
|   A|   col3|          7|
|   B|   col3|          6|
|   C|   col3|          5|
|   D|   col3|          4|
|   E|   col3|          3|
+----+-------+-----------+

注意:所有列的数据类型必须相同。

要检查列是否具有相同的数据类型,

if len(set(map(lambda x: x[-1], df.dtypes[1:]))) != 1:
    raise AssertionError("All columns must be of the same datatype")

【讨论】:

【参考方案2】:

基本上,您正在尝试取消透视列并在 spark 中,您可以按以下方式执行此操作:

from pyspark.sql.functions import expr
data.select("name",expr("stack(3,'col1',col1,'col2',col2,'col3',col3) as (new_col, new_col_val)")).show()

【讨论】:

【参考方案3】:

melt函数做起来比较简单。

sdf = spark.createDataFrame(pdf)
melt(sdf, id_vars=['name'], value_vars=['col1', 'col2', 'col3']).show()

【讨论】:

以上是关于Pyspark - 将多列数据组合成跨行分布的单列[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Pandas DataFrame 将多列值堆叠到单列中

TSQL:如何将单列的行加入/组合成 CSV 列表

合并 Spark DataFrame 中的多列 [Java]

如何在 PySpark 上将所有功能组合成一列?

将多列合并为单列[重复]

如何使用 pl/sql 中的游标将多列数据插入包含单列的表中?