将列表的列拆分为同一 PySpark 数据框中的多列

Posted

技术标签:

【中文标题】将列表的列拆分为同一 PySpark 数据框中的多列【英文标题】:Split column of list into multiple columns in the same PySpark dataframe 【发布时间】:2018-04-04 12:21:45 【问题描述】:

我有以下包含 2 列的数据框:

第一列有列名

第二列有值列表。

+--------------------+--------------------+
|              Column|            Quantile|
+--------------------+--------------------+
|                rent|[4000.0, 4500.0, ...|
|     is_rent_changed|[0.0, 0.0, 0.0, 0...|
|               phone|[7.022372888E9, 7...|
|          Area_house|[1000.0, 1000.0, ...|
|       bedroom_count|[1.0, 1.0, 1.0, 1...|
|      bathroom_count|[1.0, 1.0, 1.0, 1...|
|    maintenance_cost|[0.0, 0.0, 0.0, 0...|
|            latitude|[12.8217605, 12.8...|
|            Max_rent|[9000.0, 10000.0,...|
|                Beds|[2.0, 2.0, 2.0, 2...|
|                Area|[1000.0, 1000.0, ...|
|            Avg_Rent|[3500.0, 4000.0, ...|
|      deposit_amount|[0.0, 0.0, 0.0, 0...|
|          commission|[0.0, 0.0, 0.0, 0...|
|        monthly_rent|[0.0, 0.0, 0.0, 0...|
|is_min_rent_guara...|[0.0, 0.0, 0.0, 0...|
|min_guarantee_amount|[0.0, 0.0, 0.0, 0...|
|min_guarantee_dur...|[1.0, 1.0, 1.0, 1...|
|        furnish_cost|[0.0, 0.0, 0.0, 0...|
|  owner_furnish_part|[0.0, 0.0, 0.0, 0...|
+--------------------+--------------------+

如何将第二列拆分为多列以保留相同的数据集。

我可以使用以下方法访问这些值:

univar_df10.select("Column", univar_df10.Quantile[0],univar_df10.Quantile[1],univar_df10.Quantile[2]).show()

+--------------------+-------------+-------------+------------+
|              Column|  Quantile[0]|  Quantile[1]| Quantile[2]|
+--------------------+-------------+-------------+------------+
|                rent|       4000.0|       4500.0|      5000.0|
|     is_rent_changed|          0.0|          0.0|         0.0|
|               phone|7.022372888E9|7.042022842E9|7.07333021E9|
|          Area_house|       1000.0|       1000.0|      1000.0|
|       bedroom_count|          1.0|          1.0|         1.0|
|      bathroom_count|          1.0|          1.0|         1.0|
|    maintenance_cost|          0.0|          0.0|         0.0|
|            latitude|   12.8217605|   12.8490502|   12.863517|
|            Max_rent|       9000.0|      10000.0|     11500.0|
|                Beds|          2.0|          2.0|         2.0|
|                Area|       1000.0|       1000.0|      1000.0|
|            Avg_Rent|       3500.0|       4000.0|      4125.0|
|      deposit_amount|          0.0|          0.0|         0.0|
|          commission|          0.0|          0.0|         0.0|
|        monthly_rent|          0.0|          0.0|         0.0|
|is_min_rent_guara...|          0.0|          0.0|         0.0|
|min_guarantee_amount|          0.0|          0.0|         0.0|
|min_guarantee_dur...|          1.0|          1.0|         1.0|
|        furnish_cost|          0.0|          0.0|         0.0|
|  owner_furnish_part|          0.0|          0.0|         0.0|
+--------------------+-------------+-------------+------------+
only showing top 20 rows

我希望我的新数据框能够将我的第二列列表拆分为多个列,如上述数据集。 提前致谢。

【问题讨论】:

那么univar_df10.select() 有什么问题? 问题是什么?你似乎已经拥有了你想要的东西。 new_df = univar_df10.select("Column", univar_df10.Quantile[0],univar_df10.Quantile[1],univar_df10.Quantile[2]) 【参考方案1】:

假设(您的问题被标记为关闭,因为不清楚您在问什么)您的问题是您的 Quantile 列中的列表有一定长度,因此不方便要手动构建相应的命令,这里是使用列表添加和理解作为select 的参数的解决方案:

spark.version
# u'2.2.1'

# make some toy data
from pyspark.sql import Row
df = spark.createDataFrame([Row([0,45,63,0,0,0,0]),
                            Row([0,0,0,85,0,69,0]),
                            Row([0,89,56,0,0,0,0])],
                            ['features'])

df.show()
# result:
+-----------------------+
|features               |
+-----------------------+
|[0, 45, 63, 0, 0, 0, 0]|
|[0, 0, 0, 85, 0, 69, 0]|
|[0, 89, 56, 0, 0, 0, 0]|
+-----------------------+

# get the length of your lists, if you don't know it already (here is 7):
length = len(df.select('features').take(1)[0][0])
length
# 7

df.select([df.features] + [df.features[i] for i in range(length)]).show()
# result:
+--------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
|            features|features[0]|features[1]|features[2]|features[3]|features[4]|features[5]|features[6]|  
+--------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
|[0, 45, 63, 0, 0,...|          0|         45|         63|          0|          0|          0|          0| 
|[0, 0, 0, 85, 0, ...|          0|          0|          0|         85|          0|         69|          0|
|[0, 89, 56, 0, 0,...|          0|         89|         56|          0|          0|          0|          0|
+--------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+

所以,在你的情况下,

univar_df10.select([univar_df10.Column] + [univar_df10.Quantile[i] for i in range(length)])

应该做的工作,在你计算 length 为之后

length = len(univar_df10.select('Quantile').take(1)[0][0])

【讨论】:

如何在 scala spark 中做到这一点? @jxn 抱歉,不知道 Scala 细节 嗨@jxn 在Scala中我们可以实现这个目标。我正在使用 for with yield 来实现这一目标。检查我的答案,希望对您有所帮助。【参考方案2】:

这是在 scala 中执行此操作的伪代码:-

import org.apache.spark.sql.functions.split 
import org.apache.spark.sql.functions.col

#Create column which you wanted to be .
val quantileColumn = Seq("quantile1","qunatile2","quantile3")

#Get the number of columns
val numberOfColums = quantileColumn.size

#Create a list of column
val columList = for (i <- 0 until numberOfColums ) yield split(col("Quantile"),",").getItem(i).alias(quantileColumn(i))

#Just perfom Select operation.
df.select(columList: _ *)

# If you want some columns to be added or dropped , use withColumn & dropp on df.

【讨论】:

请使用下面的导入import org.apache.spark.sql.functions.split import org.apache.spark.sql.functions.col 请不要使用 cmets 添加材料 - 而是编辑和更新您的帖子。另外,请避免回答来自 cmets 的后续问题 - 目前的主题显然是关于 pyspark 好,我会记下来的。 请将导入添加到答案中!

以上是关于将列表的列拆分为同一 PySpark 数据框中的多列的主要内容,如果未能解决你的问题,请参考以下文章

如何使用pyspark将具有多个可能值的Json数组列表转换为数据框中的列

Pyspark:如何将现有非空列的元组列表作为数据框中的列值之一返回

遍历 pyspark 数据框中的列,而不为单个列创建不同的数据框

PySpark:将 RDD 转换为数据框中的列

使用 pyspark 将 Spark 数据框中的列转换为数组 [重复]

PySpark 将“map”类型的列转换为数据框中的多列