apache-spark - 在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 会吐出该列的扁平字符串版本。
有没有更好的办法?
解决方案
您正在尝试为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()