В моей схеме определен массив struct, где атрибутом value может быть строка, int, float или boolean.
printSchema()
root
|-- id: integer (nullable = true)
|-- custom_fields: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- id: long (nullable = true)
| | |-- value: struct (nullable = true)
| | | |-- member0: string (nullable = true)
| | | |-- member1: long (nullable = true)
| | | |-- member2: double (nullable = true)
| | | |-- member3: boolean (nullable = true)
И пример ввода:
{
"id": 1,
"custom_fields": [{
"id": 123,
"value": True
},
{
"id": 456,
"value": "awesome"
}
]
}
У меня также есть своего рода отображение для преобразования идентификаторов этих пользовательских полей в понятные имена. Как пример отображения:
{
123: 'has_bugs',
456: 'type'
}
Моя проблема: я строю список выражений, чтобы выполнить выравнивание, чтобы избежать вложенных структур, и иметь понятные имена вместо массива custom_fields:
cf_dict_mapping = { 123: 'has_bugs', 456: 'type' }
cf_spark_map = map_from_entries("custom_fields")
exprs = [cf_spark_map.getItem(i).cast("string").alias(t) for i, t in cf_dict_mapping.items()]
df = df.select(*["*"] + exprs)
Этот код почти работает, но вместо того, чтобы возвращать что-то вроде "has_bugs: true"
, он возвращает "has_bugs: ['true', '', '', '']"
.
Как я могу заставить мой код получить первый "memberX" из custom_fields
, который не равен нулю?
edit: я пробовал с coalesce
, но он не будет работать [coalesce(cf_spark_map.getItem(i).cast("string")).alias(t) for i, t in cf_dict_mapping.items()]
.