ТЕХНОЛОГИЯ ЭКСПЕДИА ГРУПП - ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ
Подробное описание функций массива Apache Spark
Практическое руководство по использованию функций массива
В этом посте мы узнаем о функциях массива Apache Spark на примерах, показывающих, как работает каждая функция. Вам также могут быть интересны мои предыдущие сообщения об Apache Spark.
- Начните свое путешествие с Apache Spark - Часть 1
- Начните свое путешествие с Apache Spark - Часть 2
- Начни свое путешествие с Apache Spark - Часть 3
- Глубокое погружение в функции Apache Spark DateTime
- Работа с JSON в Apache Spark
- Глубокое погружение в оконные функции Apache Spark
- Структурированная потоковая передача Apache Spark
Примечание: в следующих примерах используется Scala API. Для вашего удобства записная книжка Zeppelin, экспортированная как файл JSON, а также файл Scala доступны на GitHub.
Настраивать
Сначала нам нужно импортировать функции, которые мы рассмотрим в этом блоге.
Давайте создадим несколько фреймов данных Spark, которые мы будем использовать, чтобы узнать о различных функциях массивов.
Здесь мы создали два DataFrames df
и full_df
, которые содержат два столбца и три столбца соответственно.
Проверить схему
Давайте проверим схему указанного выше DataFrame full_df
Вывод показывает, что col1
- это строковый тип, а array_col1
и array_col2
- массив:
root |-- col1: string (nullable = true) |-- array_col1: array (nullable = true) | |-- element: integer (containsNull = true) |-- array_col2: array (nullable = true) | |-- element: integer (containsNull = true)
Аналогично для DataFramedf
схема выглядит так:
root |-- col1: string (nullable = true) |-- array_col2: array (nullable = true) | |-- element: integer (containsNull = true)
В следующих примерах мы будем использовать df
для функций, которые принимают один массив в качестве входных данных, и df_full
для функций, которые принимают два массива в качестве входных данных.
Функции для работы с массивами
array_contains
Если нам нужно найти определенный элемент в массиве, мы можем использовать функцию array_contains
. Эта функция возвращает истину, если значение присутствует в массиве, и ложь в противном случае.
Выход:
+----+------------------+------+ |col1| array_col2|result| +----+------------------+------+ | x| [1, 2, 3, 7, 7]| true| | z|[3, 2, 8, 9, 4, 9]| true| | a| [4, 5, 2, 8]| false| +----+------------------+------+
Мы ищем значение «3» в столбце массива array_col2
и получаем true для первых двух строк, где присутствует «3», и false для последнего столбца, поскольку «3» - это нет.
array_distinct
Эта функция возвращает только отдельные значения из массива и удаляет повторяющиеся значения.
Выход:
+----+------------------+---------------+ |col1| array_col2| result| +----+------------------+---------------+ | x| [1, 2, 3, 7, 7]| [1, 2, 3, 7]| | z|[3, 2, 8, 9, 4, 9]|[3, 2, 8, 9, 4]| | a| [4, 5, 2, 8]| [4, 5, 2, 8]| +----+------------------+---------------+
Повторяющиеся значения были удалены, и в столбце массива result
представлены только отдельные значения.
array_except
Эта функция возвращает элементы из первого массива, которых нет во втором массиве. Это логически эквивалентно установке операции вычитание.
Выход:
+----+------------------+------------------+---------+ |col1| array_col1| array_col2| result| +----+------------------+------------------+---------+ | x| [4, 6, 7, 9, 2]| [1, 2, 3, 7, 7]|[4, 6, 9]| | z|[7, 5, 1, 4, 7, 1]|[3, 2, 8, 9, 4, 9]|[7, 5, 1]| | a| [3, 8, 5, 3]| [4, 5, 2, 8]| [3]| +----+------------------+------------------+---------+
Столбец result
содержит элементы, которые присутствуют только в array_col1
, но отсутствуют в array_col2
. Например, в первой строке столбец result
содержит [4, 6, 9]
, потому что эти элементы присутствуют в array_col1
, но не в array_col2
.
array_intersect
Эта функция возвращает общие элементы из обоих массивов. Это логически эквивалентно установке операции пересечение.
Выход:
+----+------------------+------------------+------+ |col1| array_col1| array_col2|result| +----+------------------+------------------+------+ | x| [4, 6, 7, 9, 2]| [1, 2, 3, 7, 7]|[7, 2]| | z|[7, 5, 1, 4, 7, 1]|[3, 2, 8, 9, 4, 9]| [4]| | a| [3, 8, 5, 3]| [4, 5, 2, 8]|[8, 5]| +----+------------------+------------------+------+
Столбец result
содержит элементы, общие для обоих столбцов массива (array_col1
и array_col2
). Например, в первой строке столбец result
содержит [7, 2]
, потому что эти элементы присутствуют как вarray_col1
, так и в array_col2
.
array_join
Эта функция объединяет все элементы массива на основе разделителя, определенного вторым аргументом.
Выход:
+----+------------------+-----------+ |col1| array_col2| result| +----+------------------+-----------+ | x| [1, 2, 3, 7, 7]| 1,2,3,7,7| | z|[3, 2, 8, 9, 4, 9]|3,2,8,9,4,9| | a| [4, 5, 2, 8]| 4,5,2,8| +----+------------------+-----------+
Столбец result
содержит строку, которая представляет собой объединение всех элементов массива с использованием указанного разделителя (в этом примере запятая).
Примечание: если есть какие-либо значения NULL, мы можем заменить третий аргумент (nullReplacement
) любым строковым значением.
array_max
Эта функция возвращает максимальное значение из массива.
Выход:
+----+------------------+------+ |col1| array_col2|result| +----+------------------+------+ | x| [1, 2, 3, 7, 7]| 7| | z|[3, 2, 8, 9, 4, 9]| 9| | a| [4, 5, 2, 8]| 8| +----+------------------+------+
Столбец result
содержит максимальное значение из каждого массива в строке. Например, в первой строке столбец result
содержит «7», потому что это максимальный элемент в массиве [1, 2, 3, 7, 7]
.
array_min
Эта функция возвращает минимальное значение из массива.
Выход:
+----+------------------+------+ |col1| array_col2|result| +----+------------------+------+ | x| [1, 2, 3, 7, 7]| 1| | z|[3, 2, 8, 9, 4, 9]| 2| | a| [4, 5, 2, 8]| 2| +----+------------------+------+
Столбец result
содержит минимальное значение из каждого массива в строке. Например, в первой строке столбец result
содержит «1», потому что это минимальный элемент в массиве [1, 2, 3, 7, 7]
.
array_position
Эта функция возвращает позицию первого появления указанного элемента. Если элемент отсутствует, возвращается 0.
Давайте попробуем найти положение элемента, скажем, «7» из столбца array_col2
.
Выход:
+----+------------------+------+ |col1| array_col2|result| +----+------------------+------+ | x| [1, 2, 3, 7, 7]| 4| | z|[3, 2, 8, 9, 4, 9]| 0| | a| [4, 5, 2, 8]| 0| +----+------------------+------+
В первой строке мы получаем позицию «4», потому что «7» впервые встречается в позиции четыре. Для остальных строк мы получаем «0», потому что «7» отсутствует.
array_remove
Эта функция удаляет все вхождения элемента из массива.
Удалим элемент «7» из столбца array_col2
.
Выход:
+----+------------------+------------------+ |col1| array_col2| result| +----+------------------+------------------+ | x| [1, 2, 3, 7, 7]| [1, 2, 3]| | z|[3, 2, 8, 9, 4, 9]|[3, 2, 8, 9, 4, 9]| | a| [4, 5, 2, 8]| [4, 5, 2, 8]| +----+------------------+------------------+
Все вхождения элемента «7» удаляются из массива.
array_repeat
Эта функция создает массив, который повторяется, как указано вторым аргументом.
Выход:
+----+------------------+----------------------------------------+ |col1|array_col2 |result | +----+------------------+----------------------------------------+ |x |[1, 2, 3, 7, 7] |[[1, 2, 3, 7, 7], [1, 2, 3, 7, 7]] | |z |[3, 2, 8, 9, 4, 9]|[[3, 2, 8, 9, 4, 9], [3, 2, 8, 9, 4, 9]]| |a |[4, 5, 2, 8] |[[4, 5, 2, 8], [4, 5, 2, 8]] | +----+------------------+----------------------------------------+
Массив из array_col2
повторился 2 раза в столбце result
. Например, в первой строке столбец result
содержит массив [1, 2, 3, 7, 7]
twice.
array_sort
Эта функция сортирует элементы массива в порядке возрастания.
Выход:
+----+------------------+------------------+ |col1| array_col2| result| +----+------------------+------------------+ | x| [1, 2, 3, 7, 7]| [1, 2, 3, 7, 7]| | z|[3, 2, 8, 9, 4, 9]|[2, 3, 4, 8, 9, 9]| | a| [4, 5, 2, 8]| [2, 4, 5, 8]| +----+------------------+------------------+
Массив в столбце result
отсортирован по возрастанию. Например, в последней строке результат столбца содержит [2, 4, 5, 8]
, который отсортирован в порядке возрастания.
array_union
Эта функция возвращает объединение всех элементов из входных массивов.
Выход:
+------------------+------------------+------------------------+ |array_col1 |array_col2 |result | +------------------+------------------+------------------------+ |[4, 6, 7, 9, 2] |[1, 2, 3, 7, 7] |[4, 6, 7, 9, 2, 1, 3] | |[7, 5, 1, 4, 7, 1]|[3, 2, 8, 9, 4, 9]|[7, 5, 1, 4, 3, 2, 8, 9]| |[3, 8, 5, 3] |[4, 5, 2, 8] |[3, 8, 5, 4, 2] | +------------------+------------------+------------------------+
Примечание: опущено col1
, чтобы соответствовать результату здесь, в блоке кода.
Столбец result
содержит объединение массивов из столбца array_col1
и array_col2
и содержит только различные значения.
array_overlap
Эта функция проверяет, является ли хотя бы один элемент общим / перекрывающимся в массивах. Он возвращает true, если хотя бы один элемент является общим в обоих массивах, и false в противном случае. Он возвращает значение NULL, если хотя бы один из массивов имеет значение NULL.
Выход:
+----+------------------+------------------+------+ |col1|array_col1 |array_col2 |result| +----+------------------+------------------+------+ |x |[4, 6, 7, 9, 2] |[1, 2, 3, 7, 7] |true | |z |[7, 5, 1, 4, 7, 1]|[3, 2, 8, 9, 4, 9]|true | |a |[3, 8, 5, 3] |[4, 5, 2, 8] |true | +----+------------------+------------------+------+
Все значения в столбце result
равны true
, потому что у нас есть хотя бы один общий элемент в array_col1
и array_col2
для всех строк. Например, в первой строке result
столбец - это true
, потому что элементы «2» и «7» присутствуют в обоих столбцах array_col1
и array_col2
.
array_zip
Эта функция объединяет i-й элемент массива и возвращает массив ‹struct›.
Поскольку оба столбца массива имеют одинаковое количество значений, давайте удалим некоторые значения из одного столбца массива и посмотрим, как он ведет себя с разными значениями в массиве с помощью операции zip.
Сначала мы удалим элемент «2» из столбца array_col2
массива, а затем попытаемся заархивировать столбец array_col1
с вновь созданным столбцом new_array_col
Выход:
+------------------+---------------+-------------------------------+ |array_col1 |new_array_col |result | +------------------+---------------+-------------------------------+ |[4, 6, 7, 9, 2] |[1, 3, 7, 7] |[[4, 1], [6, 3] ..., [2,]] | |[7, 5, 1, 4, 7, 1]|[3, 8, 9, 4, 9]|[[7, 3], [5, 8] ..., [1,]] | |[3, 8, 5, 3] |[4, 5, 8] |[[3, 4], ... [3,]] | +------------------+---------------+-------------------------------+
В первой строке первым элементом столбца result
является [4, 1], который представляет собой zip первого элемента из массива array_col1
(4) и new_array_col
(1). Кроме того, последний элемент столбца result
- [2,] (который представляет собой zip 5-го элемента), а второе значение пусто, потому что в первой строке столбца new_array_col
нет 5-го элемента.
Давайте также проверим тип result
столбцов.
Выход:
root |-- result: array (nullable = true) | |-- element: struct (containsNull = false) | | |-- array_col1: integer (nullable = true) | | |-- new_array_col: integer (nullable = true)
Тип столбца результата - массив ‹struct›.
concat
Эта функция объединяет все элементы обоих массивов в один.
Выход:
+------------------+------------------+----------------------------+ |array_col1 |array_col2 |result | +------------------+------------------+----------------------------+ |[4, 6, 7, 9, 2] |[1, 2, 3, 7, 7] |[4, 6, 7, 9, ..., 3, 7, 7] | |[7, 5, 1, 4, 7, 1]|[3, 2, 8, 9, 4, 9]|[7, 5, 1, 4, ..., 9, 4, 9] | |[3, 8, 5, 3] |[4, 5, 2, 8] |[3, 8, 5, 3, 4, 5, 2, 8] | +------------------+------------------+----------------------------+
Столбец result
содержит массив, который представляет собой объединение массивов в столбцах array_col1
и array_col2
.
Примечание. Чтобы уместить результат, мы удалили несколько элементов из столбца result
с дисплея.
element_at
Эта функция возвращает элемент по указанному индексу.
Попробуем получить первый элемент из каждого массива.
Выход:
+----+------------------+------+ |col1|array_col2 |result| +----+------------------+------+ |x |[1, 2, 3, 7, 7] |1 | |z |[3, 2, 8, 9, 4, 9]|3 | |a |[4, 5, 2, 8] |4 | +----+------------------+------+
Столбец result
содержит первый элемент из каждого массива. Например, в первой строке result
содержит «1», потому что это первый элемент в массиве [1, 2, 3, 7, 7]
.
сплющивать
Эта функция возвращает единственный массив из массива массивов. Если массив имеет глубину более двух уровней, он удаляет один уровень вложенности из массива.
Давайте сначала сгенерируем вложенный массив, используя функцию array_repeat
, как описано выше, а затем сгладим вложенный массив.
Выход:
+-----------------------------------+------------------------------+ |repeat |result | +-----------------------------------+------------------------------+ |[[1, 2, 3, 7, 7], [1, 2, 3, 7, 7]] |[1, 2, 3, 7, 7, 1, 2, 3, 7, 7]| |[[3, 2, 8, 9, 4], [3, 2, 8, 9, 4]] |[3, 2, 8, 9, 4, 3, 2, 8, 9, 4]| |[[4, 5, 2, 8], [4, 5, 2, 8]] |[4, 5, 2, 8, 4, 5, 2, 8] | +----------------------------------------+-------------------------+
Столбец result
содержит все значения из массива массивов из столбца repeat
, но в одном массиве.
map_from_arrays
Эта функция создает столбец карты. Элементы первого столбца будут использоваться для ключей, а второй столбец - для значений.
Выход:
+------------------+------------------+--------------------+ | array_col1| array_col2| result| +------------------+------------------+--------------------+ | [4, 6, 7, 9, 2]| [1, 2, 3, 7, 7]|[4 -> 1, 6 -> 2, ...| |[7, 5, 1, 4, 7, 1]|[3, 2, 8, 9, 4, 9]|[7 -> 3, 5 -> 2, ...| | [3, 8, 5, 3]| [4, 5, 2, 8]|[3 -> 4, 8 -> 5, ...| +------------------+------------------+--------------------+
Столбец result
содержит карту, созданную из обоих входных массивов. Первый элемент в первой строке - это 4 -> 1
, где «4» - это ключ, который является первым элементом из первого столбца array_col1
, а «1» - это значение ключа, которое является первым элементом из второго столбца array_col2
.
задний ход
Эта функция меняет порядок элементов во входном массиве.
Выход:
+----+------------------+------------------+ |col1| array_col2| result| +----+------------------+------------------+ | x| [1, 2, 3, 7, 7]| [7, 7, 3, 2, 1]| | z|[3, 2, 8, 9, 4, 9]|[9, 4, 9, 8, 2, 3]| | a| [4, 5, 2, 8]| [8, 2, 5, 4]| +----+------------------+------------------+
Столбец result
содержит обратную сторону массива, присутствующего в столбце array_col2
. Например, в первой строке result
содержит [7, 7, 3, 2, 1]
, который является обратным массиву [1, 2, 3, 7, 7]
из столбца aray_col2
.
тасовать
Эта функция перемешивает элементы массива случайным образом.
Выход:
+----+------------------+------------------+ |col1| array_col2| result| +----+------------------+------------------+ | x| [1, 2, 3, 7, 7]| [2, 7, 1, 7, 3]| | z|[3, 2, 8, 9, 4, 9]|[3, 8, 9, 4, 9, 2]| | a| [4, 5, 2, 8]| [8, 4, 2, 5]| +----+------------------+------------------+
Столбец result
содержит перемешанные элементы из столбца array_col2
. Другими словами, порядок элементов в столбце result
случайный. Например, в первой строке столбец result
содержит [2, 7, 1, 7, 3]
, который представляет собой перемешанный вывод массива [1, 2, 3, 7, 7]
из столбца array_col2
.
Примечание. Попробуйте выполнить функцию перемешивания несколько раз. Порядок значений в столбце result
будет отличаться для каждого выполнения.
размер
Эта функция возвращает количество элементов в массиве или карте.
Выход:
+----+------------------+------+ |col1| array_col2|result| +----+------------------+------+ | x| [1, 2, 3, 7, 7]| 5| | z|[3, 2, 8, 9, 4, 9]| 6| | a| [4, 5, 2, 8]| 4| +----+------------------+------+
Столбец result
содержит размер (количество элементов) массива в столбце array_col2
. Например, в первой строке столбец result
содержит «5», потому что количество элементов в [1, 2, 3, 7, 7]
равно 5.
кусочек
Эта функция разбивает массив на подмассив. Мы можем указать начало индекса в качестве второго аргумента и количество элементов в качестве третьего аргумента.
Примечание. Массивы в Spark начинаются с индекса 1. Он также поддерживает отрицательную индексацию для доступа к элементам с последнего.
Давайте попробуем создать подмассив из 3 элементов, начиная с индекса 2.
Выход:
+----+------------------+---------+ |col1| array_col2| result| +----+------------------+---------+ | x| [1, 2, 3, 7, 7]|[2, 3, 7]| | z|[3, 2, 8, 9, 4, 9]|[2, 8, 9]| | a| [4, 5, 2, 8]|[5, 2, 8]| +----+------------------+---------+
В первой строке result
содержит подмассив [2, 3, 7], который создается с 3 элементами из индекса 2 в [1, 2, 3, 7
, 7].
sort_array
Эта функция по умолчанию сортирует массив в порядке возрастания. Однако мы можем отсортировать по убыванию со вторым аргументом как asc=false
.
Выход:
+----+------------------+------------------+
|col1| array_col2| result|
+----+------------------+------------------+
| x| [1, 2, 3, 7, 7]| [7, 7, 3, 2, 1]|
| z|[3, 2, 8, 9, 4, 9]|[9, 9, 8, 4, 3, 2]|
| a| [4, 5, 2, 8]| [8, 5, 4, 2]|
+----+------------------+------------------+
Столбец result
отсортирован по убыванию. Например, в первой строке столбец result
содержит [7, 7, 3, 2, 1]
, который является отсортированным по убыванию результатом array[1, 2, 3, 7, 7]
из столбца array_col2
.
взорваться
Эта функция создает новую строку для каждого элемента массива или карты.
Давайте сначала создадим новый столбец с меньшим количеством значений, которые нужно разнести.
Выход:
+----+---------+ |col1|slice_col| +----+---------+ | x| [1, 2]| | z| [3, 2]| | a| [4, 5]| +----+---------+
slice_col
содержит 2 элемента в массиве. Таким образом, после разнесения создается 2 строки для каждого массива.
Теперь попробуем взорвать столб slice_col
.
Выход:
+----+---------+------+ |col1|slice_col|result| +----+---------+------+ | x| [1, 2]| 1| | x| [1, 2]| 2| | z| [3, 2]| 3| | z| [3, 2]| 2| | a| [4, 5]| 4| | a| [4, 5]| 5| +----+---------+------+
После разнесения создаются 2 строки для каждого элемента массива в столбце slice_col
.
Posexplode
Эта функция создает новую строку для каждого элемента с позицией массива или карты.
Давайте сначала создадим новый столбец с меньшим количеством значений, которые нужно разнести.
А теперь попробуем взорвать slice_col
с позиции.
Выход:
+----+---------+---+---+ |col1|slice_col|pos|col| +----+---------+---+---+ |x |[1, 2] |0 |1 | |x |[1, 2] |1 |2 | |z |[3, 2] |0 |3 | |z |[3, 2] |1 |2 | |a |[4, 5] |0 |4 | |a |[4, 5] |1 |5 | +----+---------+---+---+
Здесь были сгенерированы еще 2 столбца как pos
(представляют позицию) и col
(представляют значение элемента).
Надеюсь, вам понравилось узнавать о работе с различными функциями массивов в Apache Spark. Для удобства на GitHub доступен блокнот, содержащий приведенные выше примеры.