【发布时间】:2020-05-03 17:49:32
【问题描述】:
我有一个类似 pyspark 的数据框 df
+-----+----+------------+------------+-------------+------------+
| Name| Age| P_Attribute|S_Attributes|P_Values |S_values |
+-----+----+------------+------------+-------------+------------+
| Bob1| 16 | [x1,x2] | [x1,x3]|["ab",1] | [1,2] |
| Bob2| 16 |[x1,x2,x3] | [] |["a","b","c"]| [] |
+-----+----+------------+------------+-------------+------------+
我想最终创建 df 如下,
+-----+----+------------+------------+
| Name| Age| Attribute | Values|
+-----+----+------------+------------+
| Bob1| 16 | x1 | ab |
| Bob1| 16 | x2 | 1 |
| Bob1| 16 | x1 | 1 |
| Bob1| 16 | x3 | 2 |
| Bob2| 16 | x1 | a |
| Bob2| 16 | x2 | b |
| Bob2| 16 | x3 | c |
+-----+----+------------+------------+
基本上我想合并这两列并将它们分解成行。在 pyspark 数组函数的帮助下,我能够连接数组并进行分解,但稍后要识别专业属性和运动属性之间的差异,因为它们可以具有相同的名称。我也需要一个类型列,
+-----+----+------------+------------+------------+
| Name| Age| Attribute| type |Value |
+-----+----+------------+------------+------------+
| Bob1| 16 | x1 | 1 | ab |
| Bob1| 16 | x2 | 1 | 1 |
| Bob1| 16 | x1 | 2 | 1 |
| Bob1| 16 | x3 | 2 | 2 |
| Bob2| 16 | x1 | 1 | a |
| Bob2| 16 | x2 | 1 | b |
| Bob2| 16 | x3 | 1 | c |
+-----+----+------------+------------+------------+
所以我最初想创建一个单独的数组列,
+-----+----+------------+------------+------------+------------+
| Name| Age| P_Attribute|S_Attributes|P_type |S_type |
+-----+----+------------+------------+------------+------------+
| Bob1| 16 | [x1,x2] | [x1,x3]| [1,1] | [2,2] |
| Bob2| 16 |[x1,x2,x3] | [] | [1,1,1] | [] |
+-----+----+------------+------------+------------+------------+
这样我就可以合并列并使用所需的类型列展开,如上面的 df 所示。 问题是我无法动态创建 P_type 和 S_type 列。 我试过下面的代码,
new_df = df.withColumn("temp_P_type", F.lit(1))\
.withColumn("P_type", F.array_repeat("temp_P_type",F.size("P_Attribute")))
这会引发 TypeError: Column is not iterable 错误。
如果列的长度已经被提取为另一列,它也不起作用。
任何人都可以帮我解决这个问题,或者是否有更好的解决方案可以做到这一点?是否可以在不使用 RDD 和 python 函数(没有 UDF)的情况下以 df 级别执行此操作?
附:我正在使用火花 2.4
【问题讨论】:
-
我想创建如下的 df, 这个预期的结果(第二个表)非常令人困惑。您是否只需要一个属性列,例如下面的第三张表?
标签: python apache-spark pyspark apache-spark-sql