将列表的 spark DF 列拆分为单独的列

Posted

技术标签:

【中文标题】将列表的 spark DF 列拆分为单独的列【英文标题】:Split spark DF column of list into individual columns 【发布时间】:2019-08-28 10:59:11 【问题描述】:

对此的scala spark实现感兴趣 split-column-of-list-into-multiple-columns-in-the-same-pyspark-dataframe

鉴于此数据框:

|              X     |            Y|
+--------------------+-------------+
|                rent|[1,2,3......]|
|     is_rent_changed|[4,5,6......]|
|               phone|[7,8,9......]|

我想要一个具有爆炸值并映射到我提供的列名称的新数据框:

colNames = ['cat','dog','mouse'....]

|              Column|cat |dog |mouse |.......|
+--------------------+---|---|--------|-------|
|                rent|1  |2  |3       |.......|
|     is_rent_changed|4  |5  |6       |.......|
|               phone|7  |8  |9       |.......|

试过了:

val out = df.select(col("X"),explode($"Y"))

但它的格式错误,我不知道如何映射到我的 colNames 列表:

X              | Y |
---------------|---|
rent           |1  |
rent           |2  |
rent           |3  |
.              |.  |
.              |.  |
is_rent_changed|4  |
is_rent_changed|5  |

在上面的链接中,python 的解决方案是使用列表推导:

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

但它没有显示如何使用提供的列名列表,因为列名只是列的索引。

【问题讨论】:

你能举个例子吗?我似乎不清楚问题中的解释。 @VihitShah 更新 【参考方案1】:

我提出了一个基于某些假设的解决方案。

1. 每个数组行将具有相同数量的元素。 2. 我们在 Array[String] 中有列名 3. 我们知道 Array 中要拆分为列的值的预期数量。
var df1 = df

df 是您的输入 DF。例如:-

+---+---------+
| id|    value|
+---+---------+
|  1|[A, B, C]|
|  2|[D, E, F]|
+---+---------+

val columns = Array("cat","dog","sheep")

columns 是列名数组。

for(i<-1 to columns.length)
df1 = df1.withColumn(columns(i-1),'value.getItem(i-1))


+---+---------+---+---+-----+
| id|    value|cat|dog|sheep|
+---+---------+---+---+-----+
|  1|[A, B, C]|  A|  B|    C|
|  2|[D, E, F]|  D|  E|    F|
+---+---------+---+---+-----+

您现在可以根据需要删除值列。希望这对你有用!

【讨论】:

'value.getItem(i-1))是否有额外报价【参考方案2】:

其实没那么复杂。dataframe 的select 所期望的只是Column 对象的列表,我们可以通过编程方式创建该列表:

val columns = List("cat", "mouse", "dog")
   .zipWithIndex
   .map case (header, idx) => $"y"(idx).alias(header) 

那么我们唯一需要做的就是在select中使用它:

val df = List(("rent", Array(1,2,3)), ("is_rent_changed", Array(3,4,5))).toDF("x", "y")
df.select($"x" :: columns : _*).show()

输出:

+---------------+---+-----+---+
|              x|cat|mouse|dog|
+---------------+---+-----+---+
|           rent|  1|    2|  3|
|is_rent_changed|  3|    4|  5|
+---------------+---+-----+---+

当然你也可以内联它。

【讨论】:

只是想补充一下,如果我有一个数组而不是列表,我应该使用+:而不是::

以上是关于将列表的 spark DF 列拆分为单独的列的主要内容,如果未能解决你的问题,请参考以下文章

根据值的数量将熊猫列拆分为多个单独的列[重复]

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

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

将文本对拆分为单独的列

将日期时间列拆分为单独的日期和时间列

如何将data.frame拆分为相等的列