Spark - 将嵌套列更新为字符串

Spark - Update a nested column to string

 |-- x: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- y: struct (nullable = true)
 |    |    |-- z: struct (nullable = true)
 |    |    |    |-- aa: string (nullable = true)

我有上面的嵌套模式,我想在其中将列 z 从结构更改为字符串。

 |-- x: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- y: struct (nullable = true)
 |    |    |-- z: string (nullable = true)

我使用的不是 Spark 3,而是 Spark 2。4.x。会更喜欢 Scala 方式,但 python 也可以工作,因为这是一次性的手动操作来回填一些过去的数据。

有没有办法用一些 udf 或任何其他方式来做到这一点?

我知道通过 to_json 很容易做到这一点,但是结构的嵌套数组导致了问题。

对于您的具体情况,您可以在 Spark 2.4 或 Spark 3.0

上使用 built-in 函数来完成

Spark 2.4

您可以按如下方式使用arrays_zip

  • 首先,为每个要作为数组的结构元素的字段创建数组
  • 其次,您使用 arrays_zip 压缩这些字段

这是完整的代码,df 您的输入数据框:

import org.apache.spark.functions.{arrays_zip, col}

df.withColumn("x",
      arrays_zip(
        col("x").getField("y").alias("y"),
        col("x").getField("z").getField("aa").alias("z")
      ))

Spark 3.0

您可以使用transform重建数组的元素结构,如下所示:

df.withColumn("x", transform(
      col("x"),
      element => struct(
        element.getField("y").alias("y"),
        element.getField("z").getField("aa").alias("z")
      )
    ))

转换为高阶函数

df3=df.withColumn('x', expr('transform(x, s-> struct(s.y as y,cast(to_json(s.z) as string) as z))')).printSchema()

root
 |-- x: array (nullable = true)
 |    |-- element: struct (containsNull = false)
 |    |    |-- y: struct (nullable = true)
 |    |    |-- z: string (nullable = true)