Краткий ответ - нет , вам нужно реализовать свой UDF для агрегирования по столбцу массива.По крайней мере, в последней версии Spark (2.3.1 на момент написания).Что, как вы правильно утверждаете, не очень эффективно, так как заставляет вас либо разбирать строки, либо платить за сериализацию и десерилизацию работы в API набора данных.
Для других, кто может найти этот вопрос, написать агрегаты вбезопасный для типов способ с наборами данных, вы можете использовать API Aggregator , который, по общему признанию, недостаточно хорошо документирован и с которым очень сложно работать, поскольку сигнатуры типов становятся довольно многословными.
Более длинный ответ заключается в том, что эта функциональность скоро появится (?) в Apache Spark 2.4.
Родительский выпуск SPARK-23899 добавляет:
- array_max
- array_min
- агрегат
- map
- array_distinct
- array_remove
- array_join
и многие другие
Этот доклад " Расширение Spark SQL API с помощью более простых в использовании операций типов массивов"был представлен на Spark + в июне 2018 годаAI Summit и охватывает новую функциональность.
Если бы она была выпущена, это позволило бы вам использовать функцию max
, как в вашем примере, однако average
немного сложнее.Как ни странно, array_sum отсутствует, но он может быть построен из функции aggregate
.Вероятно, это будет выглядеть примерно так:
def sum_array(array_col: Column) = aggregate($"my_array_col", 0, (s, x) => s + x, s => s)
df.select(sum_array($"my_array_col")
Где нулевое значение - это начальное состояние буфера агрегата.
Как вы указали, size
уже может получить длину массива., что означает, что можно было бы рассчитать среднее значение.