PySpark Разбор вложенного массива структуры - PullRequest
0 голосов
/ 06 октября 2019

Я хотел бы проанализировать и получить значение конкретного ключа из фрейма данных PySpark SQL со следующим форматом

Я мог бы добиться этого с помощью UDF, но для обработки 40 столбцов с помощью команды требуется почти 20 минутJSON размером 100 МБ. Пробовал также взорваться, но он дает отдельные строки для каждого элемента массива. но мне нужно только конкретное значение ключа в данном массиве структуры.

Формат

array<struct<key:string,value:struct<int_value:string,string_value:string>>>

Функция для получения значений конкретного ключа

def getValueFunc(searcharray, searchkey):
    for val in searcharray:
        if val["key"] == searchkey:
            if val["value"]["string_value"] is not None:
                actual = val["value"]["string_value"]
                return actual
            elif val["value"]["int_value"] is not None:
                actual = val["value"]["int_value"]
                return str(actual)
            else:
                return "---"

.....
getValue = udf(getValueFunc, StringType())
....
# register the name rank udf template
spark.udf.register("getValue", getValue)
.....
df.select(getValue(col("event_params"), lit("category")).alias("event_category"))

1 Ответ

0 голосов
/ 07 октября 2019

Для Spark 2.40+ вы можете использовать функцию SparkSQL filter () , чтобы найти первый элемент массива, который соответствует key == serarchkey, а затем получить его значение. Ниже приведен шаблон фрагмента Spark SQL ( searchkey в качестве переменной) для выполнения первой части, упомянутой выше.

stmt = '''filter(event_params, x -> x.key == "{}")[0]'''.format(searchkey)

Запустите вышеуказанный stmt с expr()назначьте значение ( StructType ) временному столбцу f1, а затем используйте функцию coalesce() для получения ненулевого значения.

from pyspark.sql.functions import expr

df.withColumn('f1', expr(stmt)) \
    .selectExpr("coalesce(f1.value.string_value, string(f1.value.int_value),'---') AS event_category") \
    .show()

Дайте мне знатьесли у вас возникли проблемы с запуском вышеуказанного кода.

...