Как разбить датасет на партиции с помощью partitionby

Чтение больших данных (Big Data) занимает время. Одним из способов работы с большими объемам является разбиение большого датасет на части, или партиции. Сегодня мы поговорим о создании партиций в Apache Spark на примере функции partitionBy.

Что такое партицирование в Apache Spark

Код курса
SPOT
Ближайшая дата курса
по запросу
Продолжительность
ак.часов
Стоимость обучения
0 руб.

Партицирование (partitioning) — это процесс разбиение данных на части на основе уникальных значений столбца(ов). Когда создается фрейм данных из чтения файла или основе другого фрейма, Spark создает определенное число партиций в оперативной памяти. Это одно из преимуществ Spark над Pandas. Преобразования на партициях будут выполняться быстрее за счет параллельных вычислений.

Apache spark поддерживает два вида партиций: в оперативной памяти в виде фрейма данных (DataFrame) и на диске в виде файла:

  1. Партиция в памяти выполняется с помощью вызовов repartition или coalesce.
  2. Партиция на диске выполняется с помощью вызова partitionBy (это аналогично партициям в Hive).

В чем преимущества партиций

Apache Spark предназначен для обработки больших данных (Big Data), и партиции являются одним из способов это сделать. К плюсам партиций относятся:

  • быстрый доступ к данным;
  • возможность производить операции на меньших датасетах.

Пример создания партиций на диске

Возьмем для примера датасет с цветками iris.

df = spark.read.csv("iris.csv", header=True)
df.show()
"""
+------------+-----------+------------+-----------+-------+
|sepal_length|sepal_width|petal_length|petal_width|species|
+------------+-----------+------------+-----------+-------+
|         5.1|        3.5|         1.4|        0.2| setosa|
|         4.9|        3.0|         1.4|        0.2| setosa|
|         4.7|        3.2|         1.3|        0.2| setosa|
|         4.6|        3.1|         1.5|        0.2| setosa|
+------------+-----------+------------+-----------+-------+
"""

Функция partitionBy объекта DataFrameWriter принимает в качестве параметров названия столбцов, на основе которых будут разбиты партиции. Количество партиций будет зависеть от уникальных значений заданных столбцов.

Объект DataFrameWriter создается через вызов write. Давайте создадим партиции по столбцу species:

df.write.option("header", "true") \
  .partitionBy("species") \
  .mode("overwrite") \
  .csv("partitions")

Здесь мы создали партиции в директории partitions (она будет создана, если её не существует). В этой директории в свою очередь будут созданы директории, каждая из которых содержит партиции в виде CSV-файла (поскольку мы указали именно этот формат). Взглянем на эту директорию:

$ ls partitions/
'species=setosa'  'species=versicolor'  'species=virginica'   _SUCCESS
$ ls partitions/species\=setosa
part-00000-8c0e7028-7536-435d-982d-31f8e9d8bcac.c000.csv
$ head part-00000-8c0e7028-7536-435d-982d-31f8e9d8bcac.c000.csv
sepal_length,sepal_width,petal_length,petal_width
5.1,3.5,1.4,0.2
4.9,3.0,1.4,0.2
4.7,3.2,1.3,0.2
4.6,3.1,1.5,0.2
5.0,3.6,1.4,0.2
5.4,3.9,1.7,0.4
4.6,3.4,1.4,0.3
5.0,3.4,1.5,0.2
4.4,2.9,1.4,0.2

Как видим, было создано 3 партиции: ровно столько содержатся уникальных значений в столбце species в нашем датасете:

df.select("species").distinct().show()
"""
+----------+
|   species|
+----------+
| virginica|
|versicolor|
|    setosa|
+----------+
"""

При создании партиций лучше выбирать столбцы с категориальными значениями. Иначе, рискуете создать множество файлов, поскольку мы не выбираем число партиций (в олтичие от бакетов, о котором говорили тут), а чтение с диска — операция медленная.

Чтение партиций

Чтение партиций с диска осуществляется точно таким же образом, как и чтение обычного файла. Пример кода на Python:

df_setosa = spark.read.csv("partitions/species=setosa/", header=True)
df_setosa.show()
"""
+------------+-----------+------------+-----------+
|sepal_length|sepal_width|petal_length|petal_width|
+------------+-----------+------------+-----------+
|         5.1|        3.5|         1.4|        0.2|
|         4.9|        3.0|         1.4|        0.2|
|         4.7|        3.2|         1.3|        0.2|
|         4.6|        3.1|         1.5|        0.2|
+------------+-----------+------------+-----------+
"""

Можно заметить, что Spark не держит столбец, по которому осуществлялось деление, ведь все равно он бы был заполнен одним и тем же значением.

Еще больше подробностей о партициях в Apache Spark вы узнаете на наших образовательных курсах в лицензированном учебном центре обучения и повышения квалификации руководителей и ИТ-специалистов (менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data) в Москве:

Записаться на курс

Смотреть раcписание

Добавить комментарий

Поиск по сайту