如何修改Pyspark DataFrame中的嵌套结构列

4

我尝试对嵌套列进行匿名化/哈希处理,但未能成功。模式看起来像这样:

-- abc: struct (nullable = true)
|    |-- xyz: struct (nullable = true)
|    |    |-- abc123: string (nullable = true)
|    |    |-- services: struct (nullable = true)
|    |    |    |-- service: array (nullable = true)
|    |    |    |    |-- element: struct (containsNull = true)
|    |    |    |    |    |-- type: string (nullable = true)
|    |    |    |    |    |-- subtype: string (nullable = true)

我需要更改(匿名/哈希)type列的值。

1个回答

5
对于 Spark 3.1+,有一个列方法 withField 可用于更新结构字段。
假设这是您的输入数据框架(与您提供的模式相对应):
from pyspark.sql import Row

df = spark.createDataFrame([
    Row(abc=Row(xyz=Row(abc123="value123", services=[Row(type="type1", subtype="subtype1")])))
])

df.show(truncate=False)
#+---------------------------------+
#|abc                              |
#+---------------------------------+
#|{{value123, [{type1, subtype1}]}}|
#+---------------------------------+

您可以使用transform对数组services中的每个结构元素的字段type进行哈希处理(这里我使用xxhash64函数进行说明),如下所示:
import pyspark.sql.functions as F

df2 = df.withColumn(
    "abc",
    F.col("abc").withField(
        "xyz",
        F.col("abc.xyz").withField(
            "services",
            F.expr("transform(abc.xyz.services, x -> struct(xxhash64(x.type) as type, x.subtype))")
        )
    )
)

df2.show(truncate=False)
#+-----------------------------------------------+
#|abc                                            |
#+-----------------------------------------------+
#|{{value123, [{2134479862461603894, subtype1}]}}|
#+-----------------------------------------------+

对于较旧版本的Spark,您需要重新创建整个结构体以更新字段,当有许多嵌套字段时,这使得操作繁琐。在您的情况下,操作会像这样:

df2 = df.withColumn(
    "abc",
    F.struct(
        F.struct(
            F.col("abc.xyz.abc123"),
            F.expr(
                "transform(abc.xyz.services, x -> struct(xxhash64(x.type) as type, x.subtype))"
            ).alias("services")
        ).alias("xyz")
    )
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接