уплощение массива структуры в pyspark - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть файл XML, преобразованный в фрейм данных с использованием пакета spark- 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]

Когда я использую функцию сглаживания, я получаю сообщение об ошибке:

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, который выплевывает версию столбца в виде плоской строки.

Есть ли лучший способ?

1 Ответ

2 голосов
/ 24 февраля 2020

Вы пытаетесь применить функцию flatten для массива структур, в то время как она ожидает массив массивов:

flatten(arrayOfArrays) - Преобразует массив массивов в один массив.

Вам не нужна UDF, вы можете просто transform элементы массива из структуры в массив, а затем использовать 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()
...