首页 > 解决方案 > 在pyspark中展平结构数组

问题描述

我有一个使用 spark-xml 包转换为数据框的 XML 文件。数据框具有以下结构:

root
 |-- results: struct (nullable = true)
 |    |-- result: struct (nullable = true)
 |    |    |-- categories: struct (nullable = true)
 |    |    |    |-- category: array (nullable = true)
 |    |    |    |    |-- element: struct (containsNull = true)
 |    |    |    |    |    |-- value: string (nullable = true)

如果我选择类别列(可能在类别下出现多次):

df.select((col('results.result.categories.category')).alias("result_categories"))

对于一条记录,结果将如下所示

[[result1], [result2]]

我正在尝试使结果变平:

[result1, result2]

当我使用 flatten 函数时,我收到一条错误消息:

df.select(flatten(col('results.result.categories.category')).alias("Hits_Category"))
 cannot resolve 'flatten(`results`.`result`.`categories`.`category`)' due to data type mismatch: The argument should be an array of arrays, but '`results`.`result`.`categories`.`category`' is of array<struct<value:string>

我最终创建了一个 udf,并将该列传递给 udf,该 udf 会吐出该列的扁平字符串版本。

有没有更好的办法?

标签: apache-sparkpysparkapache-spark-sqlpyspark-dataframes

解决方案


您正在尝试为flatten结构数组应用函数,而它需要一个数组数组:

flatten(arrayOfArrays)- 将数组数组转换为单个数组。

您不需要 UDF,您可以简单地transform将数组元素从 struct 到 array,然后使用flatten.

像这样的东西:

df.select(col('results.result.categories.category').alias("result_categories"))\
  .withColumn("result_categories", expr("transform(result_categories, x -> array(x.*))"))\
  .select(flatten(col("result_categories")).alias("Hits_Category"))\
  .show()

推荐阅读