有效地 transpose/explode 将数据帧列以新的 table/dataframe 格式 [pyspark]
Efficiently transpose/explode spark dataframe columns into rows in a new table/dataframe format [pyspark]
如何以这种方式有效地分解 pyspark 数据框:
+----+-------+------+------+
| id |sport |travel| work |
+----+-------+------+------+
| 1 | 0.2 | 0.4 | 0.6 |
+----+-------+------+------+
| 2 | 0.7 | 0.9 | 0.5 |
+----+-------+------+------+
我想要的输出是这样的:
+------+--------+
| c_id | score |
+------+--------+
| 1 | 0.2 |
+------+--------+
| 1 | 0.4 |
+------+--------+
| 1 | 0.6 |
+------+--------+
| 2 | 0.7 |
+------+--------+
| 2 | 0.9 |
+------+--------+
| 2 | 0.5 |
+------+--------+
首先,您可以将 3 列放入 array
,然后 arrays_zip
,然后 explode
,然后用 .*
解压,然后 select
并重命名解压缩的列。
df.withColumn("zip", F.explode(F.arrays_zip(F.array("sport","travel","work"))))\
.select("id", F.col("zip.*")).withColumnRenamed("0","score").show()
+---+-----+
| id|score|
+---+-----+
| 1| 0.2|
| 1| 0.4|
| 1| 0.6|
| 2| 0.7|
| 2| 0.9|
| 2| 0.5|
+---+-----+
您也可以在没有 arrays_zip 的情况下执行此操作(如 cPak 所述)。 Arrays_zip 用于将不同数据帧列中的数组组合成结构形式,以便您可以将它们全部分解在一起,然后 select 与 .* 。对于这种情况,您可以使用:
df.withColumn("score", F.explode((F.array(*(x for x in df.columns if x!="id"))))).select("id","score").show()
如何以这种方式有效地分解 pyspark 数据框:
+----+-------+------+------+
| id |sport |travel| work |
+----+-------+------+------+
| 1 | 0.2 | 0.4 | 0.6 |
+----+-------+------+------+
| 2 | 0.7 | 0.9 | 0.5 |
+----+-------+------+------+
我想要的输出是这样的:
+------+--------+
| c_id | score |
+------+--------+
| 1 | 0.2 |
+------+--------+
| 1 | 0.4 |
+------+--------+
| 1 | 0.6 |
+------+--------+
| 2 | 0.7 |
+------+--------+
| 2 | 0.9 |
+------+--------+
| 2 | 0.5 |
+------+--------+
首先,您可以将 3 列放入 array
,然后 arrays_zip
,然后 explode
,然后用 .*
解压,然后 select
并重命名解压缩的列。
df.withColumn("zip", F.explode(F.arrays_zip(F.array("sport","travel","work"))))\
.select("id", F.col("zip.*")).withColumnRenamed("0","score").show()
+---+-----+
| id|score|
+---+-----+
| 1| 0.2|
| 1| 0.4|
| 1| 0.6|
| 2| 0.7|
| 2| 0.9|
| 2| 0.5|
+---+-----+
您也可以在没有 arrays_zip 的情况下执行此操作(如 cPak 所述)。 Arrays_zip 用于将不同数据帧列中的数组组合成结构形式,以便您可以将它们全部分解在一起,然后 select 与 .* 。对于这种情况,您可以使用:
df.withColumn("score", F.explode((F.array(*(x for x in df.columns if x!="id"))))).select("id","score").show()