【发布时间】:2021-02-17 20:17:01
【问题描述】:
我想对长度为 可变 (0-4000) 的数组字段应用逻辑并将其拆分为列。具有爆炸、创建新列和重命名列的 udf 可以完成这项工作,但我不确定如何将其作为 udf 迭代应用。 UDF 将采用可变长度数组字段并将一组新列 (0-4000) 返回到数据帧。如下所示的示例输入数据框
+--------------------+--------------------+
| hashval| dec_spec (array|
+--------------------+--------------------+
|3c65252a67546832d...|[8.02337424829602...|
|f5448c29403c80ea7...|[7.50372884795069...|
|94ff32cd2cfab9919...|[5.85195317398756...|
+--------------------+--------------------+
输出应该是这样的
+--------------------+--------------------+
| hashval| dec_spec (array| ftr_1 | ftr_2 | ftr_3 |...
+--------------------+--------------------+-----------+---------+--------+
|3c65252a67546832d...|[8.02337424829602...| 8.023 | 3.21 | 4.23.....
|f5448c29403c80ea7...|[7.50372884795069...| 7.502 | 8.23 |2.125
|94ff32cd2cfab9919...|[5.85195317398756...|
+--------------------+--------------------+
udf 可以采用如下的一些逻辑
df_grp = df2.withColumn("explode_col", F.explode_outer("dec_spec"))
df_grp = df_grp.groupBy("hashval").pivot("explode_col").agg(F.avg("explode_col"))
下面用于重命名列
count = 1
for col in df_grp.columns:
if col != "hashval":
df_grp = df_grp.withColumnRenamed(col, "ftr"+str(count))
count = count+1
感谢任何帮助。
PS 上面的代码,在这里得到了论坛其他人的帮助。
【问题讨论】:
-
您的列 dec_spec 长度不同?但想爆炸到 4000 列?
-
数组长度不同。因此,如果特定行只有 20 个元素,那么它将是 20 列。某些行中的数组字段可以有 2048 个元素,那么将有 2048 列。但我需要处理的最大值是 4000。超过此值的任何东西,我都可以扔掉
-
所以其余列将为空,对吧?
-
是的;如果第一行只有 20 个元素,第二行数组字段有 40 个元素,那么对于第一行,第 20 列之后将为空表字段将包含长度不等的数组,最大值为 4000。我可以在之后丢弃那个。
-
查看答案,在我的情况下,我使用 3 作为我的输入长度,请更改为 4000 并适用于您的问题