У меня есть набор данных с несколькими столбцами, которые являются массивами StructType. Моя конечная цель состоит в том, чтобы удалить одно или несколько полей из каждого, в то время как другие сохраняют структуру набора данных. В приведенном ниже примере будет показан только один такой столбец, чтобы упростить вопрос.
Исходные данные считываются из xml, который не использует элемент valuse, что приводит к появлению пустых полей _VALUE в каждой структуре. Простой стартовый вариант использования
Я хотел бы удалить поле _VALUE в примере.
Упрощенная схема:
root
|-- Option
| |-- element: struct (containsNull = true)
| | |-- _VALUE: string (nullable = true)
| | |-- _codeName: string (nullable = true)
| | |-- _optionName: string (nullable = true)
| | |-- _optionType: string (nullable = true)
a select.show столбца Option показывает это:
[[, option_A, Option A, type_1], [, option_B, Option B, type_1], [, option_C, Option C, type_2]]
[[, option_A, Option A, type_1], [, option_B, Option B, type_1], [, option_C, Option C, type_2]]
[[, option_E, Option E, type_2], [, option_C, Option C, type_2], [, option_B, Option B, type_1], [, option_A, Option A, type_1], [, option_D, Option D, type_3]]
[[, option_C, Option C, type_2], [, option_B, Option B, type_1], [, option_A, Option A, type_1]]
Я обнаружил Удаление вложенного столбца из Spark DataFrame при попытке удалить вложенный столбец _VALUE. Начиная с решения java, предоставляемого @LiorChaga, я добавил логику для массивов из решения scala над ним @ user3794759. Это приводит к удалению нужного столбца, но природа выражения собирает каждое внутреннее поле в свой собственный массив, охватывающий весь массив (т. Е. Изменяет «массив структур» в «одну структуру с массивами»:
[[option_A, option_B, option_C], [Option A, Option B, Option C], [type_1, type_1, type_2]]
[[option_A, option_B, option_C], [Option A, Option B, Option C], [type_1, type_1, type_2]]
[[option_E, option_C, option_B, option_A, option_D], [Option E, Option C, Option B, Option A, Option D], [type_2, type_2, type_1, type_1, type_3]]
[[option_C, option_B, option_A], [Option C, Option B, Option A], [type_2, type_1, type_1]]
Эта логика, кажется, обрабатывает массивы простых типов, но не вложенные структуры. Я пробовал различные модификации в построенном выражении столбца, но так как оператор по сути является выбором, упоминание полей по имени собирает их вместе. Я даже использовал решение scala, и результат тот же.
Ближайшее результирующее выражение столбца для Option:
массив (named_struct (NamePlaceholder (), Option ['_ codeName'] AS _codeName
, NamePlaceholder (), Option ['_ optionName'] AS _optionName
, NamePlaceholder (), Option ['_ optionType'] AS _optionType
))
Попытка указать, что внутренние столбцы не работают. Может быть, есть способ структурировать это так, чтобы он указывал поля, которые я хочу внутри каждого экземпляра структуры, а не создавал единственную структуру, которая собирала массивы со значением каждого поля, но я не могу понять это.
Подводя итог: есть ли способ отбрасывать поля внутри структуры, когда эта структура находится в столбце массива произвольного размера? Кажется, что попытка адаптировать решения из упомянутого вопроса не сработает, так как это всегда приводит к «отбору» оставшихся полей по имени, при котором они группируются по полю, а не группируются в исходном. экземпляр структуры.
Альтернативно: есть ли способ напрямую манипулировать схемой? Или создать новый набор данных из оригинала с новой схемой, которая автоматически сопоставляет нужные столбцы, оставляя после себя пропущенные?
1) В идеале я хотел бы сохранить решение на Java, чтобы оно соответствовало остальной части кодовой базы, но я могу использовать scala, если Java не жизнеспособна.
2) Я ищу общее / динамическое решение. Мне нужно сделать это для нескольких полей внутри нескольких сложных столбцов, и я бы не стал указывать столбцы вручную по имени в выражении.
3) Мне нужно сбросить поля по имени. Это не всегда потому, что они нулевые. Некоторые удаляются независимо от содержания.
4) Поскольку я должен сделать это для нескольких столбцов, я бы предпочел решение, которое не включает в себя разбиение каждого столбца массива, так как это приведет к созданию, возможно, десятков строк для каждой начальной строки.
5) Я все еще довольно новичок в Spark, так что, возможно, есть какое-то очевидное решение, и я просто не знаю концепции или терминологии, чтобы найти его самостоятельно. Не стесняйтесь объяснять.
Спасибо за любой совет или помощь.