Parquet: быстрое столбцовое хранилище
Записывайте DataFrame Pandas в Parquet с помощью to_parquet(), читайте его быстрее, чем CSV, и используйте выбор столбцов, чтобы загружать только нужные поля.
«Parquet: быстрое столбцовое хранилище» — бесплатный урок Pandas & NumPy Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Pandas & NumPy Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Pandas & NumPy Academy содержит 4 уроков всего.
Что такое Parquet
Apache Parquet — это двоичный столбцовый формат файла, предназначенный для аналитических задач. В отличие от CSV, который хранит данные построчно в виде текста, Parquet сохраняет каждый столбец в непрерывном блоке, эффективно сжимает его и кодирует метаданные. Поэтому запросы, читающие лишь несколько столбцов широкой таблицы, выполняются значительно быстрее. Parquet — фактически стандартный формат в озёрах данных (AWS S3, Google Cloud Storage); его изначально поддерживают Pandas, Dask, Spark и BigQuery.
Запись Parquet с помощью to_parquet()
Преобразование Pandas DataFrame в Parquet выполняется одним вызовом метода: df.to_parquet('output.parquet'). По умолчанию используется механизм pyarrow (установите его командой pip install pyarrow). Parquet точно сохраняет типы данных столбцов — даты больше не считываются обратно как строки. Формат также изначально поддерживает сжатие с помощью параметра compression; 'snappy' обеспечивает быстрое чтение и запись при умеренном сжатии, а 'gzip' даёт более высокую степень сжатия за счёт скорости.
import pandas as pd
import numpy as np
# Create a sample DataFrame
np.random.seed(0)
df = pd.DataFrame({
'date': pd.date_range('2024-01-01', periods=100000, freq='T'),
'value': np.random.randn(100000),
'category': np.random.choice(['A', 'B', 'C'], 100000)
})
# Write to Parquet
df.to_parquet('data.parquet', index=False, compression='snappy')
print('Written to data.parquet')Чтение Parquet с помощью read_parquet()
pd.read_parquet('output.parquet') считывает файл обратно в DataFrame. По сравнению с чтением эквивалентного CSV чтение Parquet обычно выполняется в 5–10 раз быстрее для широких таблиц с большим количеством столбцов. Типы данных сохраняются точно: даты остаются datetime64, категории — category, а целые числа — int32 или int64, как было сохранено. Выводить типы данных не требуется, поскольку метаданные встроены в файл.
import pandas as pd
import time
# Read Parquet
start = time.time()
df = pd.read_parquet('data.parquet')
print(f'Read Parquet: {time.time()-start:.3f}s')
print(df.dtypes)
print(df.shape)Отбор столбцов: чтение только нужных столбцов
Главное преимущество столбцового хранения — отбор столбцов: можно прочитать только определённые столбцы, не сканируя остальную часть файла. Передайте список имён столбцов параметру columns. Если в таблице 100 столбцов и каждый занимает 100 MB, а Вам нужны только 3 столбца, Parquet прочитает 3 MB вместо 10 GB. CSV должен просмотреть каждый символ, чтобы извлечь любой столбец. Поэтому Parquet идеально подходит для широких таблиц в аналитических конвейерах.
import pandas as pd
# Only load the 2 columns needed for this analysis
df = pd.read_parquet('large_table.parquet',
columns=['date', 'revenue'])
print(df.columns.tolist())
print(df.shape)
print(df.memory_usage(deep=True).sum() / 1e6, 'MB loaded')Фильтрация групп строк (проталкивание предикатов)
Parquet хранит статистику (минимальное и максимальное значения) для каждой группы строк (блока строк) в конце файла. Когда Вы применяете фильтр через параметр filters, средство чтения пропускает целые группы строк, в которых фильтр не может найти совпадение. Это называется проталкиванием предикатов. Например, при фильтрации дат в отсортированном по времени файле Parquet пропускаются целые блоки месяцев, не попадающие в диапазон, и читаются только нужные фрагменты. Механизм pyarrow изначально поддерживает эту возможность.
import pandas as pd
# Filter using predicate pushdown — row groups outside range are skipped
df = pd.read_parquet(
'time_series.parquet',
columns=['date', 'value'],
filters=[('date', '>=', '2024-06-01'),
('date', '<', '2024-07-01')]
)
print(f'Loaded {len(df):,} rows (June only)')
print(df.head())Parquet и CSV: сравнение
Ниже приведено практическое сравнение Parquet и CSV для набора данных из 10 миллионов строк и 20 столбцов:
- Размер файла: CSV — около 2 GB, Parquet (snappy) — около 400 MB
- Время чтения (все столбцы): CSV — около 15 с, Parquet — около 2 с
- Время чтения (3 столбца): CSV — около 15 с (необходимо просканировать всё), Parquet — около 0,3 с
- Сохранение типов данных: CSV теряет типы данных, Parquet сохраняет их
- Удобочитаемость для человека: CSV — да, Parquet — нет (двоичный формат)
Для производственных конвейеров, где данные записываются один раз, а читаются много раз, Parquet почти всегда является лучшим выбором.
Разделённые наборы данных Parquet
Для очень больших наборов данных Parquet поддерживает разделённые наборы данных: данные распределяются по нескольким файлам, организованным в иерархии каталогов по значениям столбцов. Например, разделение по году и месяцу создаёт путь data/year=2024/month=01/part.parquet. При чтении разделённого набора данных каталоги, соответствующие запросу, фильтруются автоматически. Это стандартная структура для озёр данных, позволяющая эффективно выполнять запросы по диапазонам для миллиардов строк.
import pandas as pd
# Write a partitioned dataset (requires pyarrow)
df = pd.read_parquet('all_data.parquet')
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
df.to_parquet(
'partitioned_data/',
partition_cols=['year', 'month'],
index=False
)
# Creates: partitioned_data/year=2024/month=1/part-0.parquet etc.Чтение разделённых наборов данных
Чтение каталога с разделённым Parquet выполняется так же, как чтение одного файла: Pandas (через pyarrow) автоматически обнаруживает все файлы разделов. Значения столбца, по которому выполнено разделение, включаются в результирующий DataFrame как столбцы. Также можно использовать filters для отбора разделов: целые поддеревья каталогов пропускаются на основе значений столбца разделения. Благодаря этому запрос к разделённому набору данных размером 1 TB выполняется почти так же, как чтение нескольких MB.
import pandas as pd
# Read the entire partitioned dataset
df_all = pd.read_parquet('partitioned_data/')
print('All years:', df_all['year'].unique())
# Read only 2024 data using partition pruning
df_2024 = pd.read_parquet(
'partitioned_data/',
filters=[('year', '==', 2024)]
)
print('2024 rows:', len(df_2024))Parquet в Dask
Dask изначально поддерживает чтение и запись Parquet с помощью dd.read_parquet() и ddf.to_parquet(). Каждый файл в каталоге с разделённым Parquet становится одной партицией Dask, что обеспечивает полностью параллельное чтение. Dask также использует проталкивание предикатов, если указаны фильтры. Запись большого результата Dask в разделённый набор данных Parquet — стандартный способ формировать выходные данные в современных инженерных конвейерах данных.
import dask.dataframe as dd
# Read partitioned Parquet with Dask (each file = one partition)
ddf = dd.read_parquet('partitioned_data/',
columns=['date', 'revenue', 'region'],
filters=[('year', '==', 2024)])
# Compute aggregation in parallel
result = ddf.groupby('region')['revenue'].sum().compute()
print(result.sort_values(ascending=False))Варианты сжатия и кодирования
Parquet поддерживает несколько алгоритмов сжатия и схем внутреннего кодирования. Snappy (по умолчанию) отдаёт приоритет скорости при умеренном сжатии. Gzip уменьшает размер файлов примерно на 30%, но замедляет чтение и запись. Zstd лучше сочетает скорость и сжатие, чем оба этих варианта. Для целочисленных столбцов Parquet автоматически применяет дельта-кодирование или словарное кодирование, дополнительно уменьшая размер без какой-либо дополнительной настройки.
import pandas as pd
import numpy as np
np.random.seed(0)
df = pd.DataFrame({'id': range(500000), 'val': np.random.randn(500000)})
for comp in ['snappy', 'gzip', 'zstd']:
fname = f'data_{comp}.parquet'
df.to_parquet(fname, compression=comp, index=False)
import os
size_mb = os.path.getsize(fname) / 1e6
print(f'{comp}: {size_mb:.2f} MB')Замена CSV в Вашем конвейере
Самый простой способ внедрить Parquet — добавить однократный этап преобразования в начале проекта: один раз прочитать CSV, очистить данные и преобразовать их типы, а затем сохранить результат в Parquet. При всех последующих запусках вместо CSV будет читаться файл Parquet. Это сразу даёт преимущества по скорости и объёму хранилища при минимальных изменениях кода. Для новых данных, поступающих в формате CSV (например, ежедневных экспортов), добавьте в конвейер этап преобразования, который записывает данные в Parquet до начала любого анализа.
import pandas as pd
# One-time conversion
df = pd.read_csv('raw_data.csv',
parse_dates=['date'],
dtype={'category': 'category',
'amount': 'float32'})
df.to_parquet('clean_data.parquet', index=False)
# All future reads use Parquet
df_fast = pd.read_parquet('clean_data.parquet')
print('Loaded from Parquet:', df_fast.dtypes.to_dict())Быстрая проверка
Проверьте, насколько хорошо Вы усвоили концепции анализа данных из этого урока.
Повторение урока
В этом уроке Вы узнали, что to_parquet() и read_parquet() обеспечивают более быстрый и компактный ввод-вывод файлов с сохранением типов данных по сравнению с CSV, отбор столбцов с параметром columns позволяет читать только нужные столбцы, избегая полного сканирования файла, а разделённые наборы данных Parquet, организованные по значениям столбцов, обеспечивают отбор разделов для эффективных запросов по диапазонам в больших озёрах данных. Далее мы подключим Pandas к реляционным базам данных с помощью SQLAlchemy.
Изучай Python с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 30
- Уроки
- 120
Часто задаваемые вопросы
Урок «Parquet: быстрое столбцовое хранилище» бесплатный?
Да — полный текст урока «Parquet: быстрое столбцовое хранилище» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Pandas & NumPy Academy, подпишись на CoddyKit PRO. Курс Pandas & NumPy Academy содержит 4 уроков всего.
Чему я научусь в уроке «Parquet: быстрое столбцовое хранилище»?
Записывайте DataFrame Pandas в Parquet с помощью to_parquet(), читайте его быстрее, чем CSV, и используйте выбор столбцов, чтобы загружать только нужные поля. Ты практикуешь Pandas & NumPy Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Pandas & NumPy Academy?
Предыдущий опыт не требуется. Pandas & NumPy Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Parquet: быстрое столбцовое хранилище»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Pandas & NumPy Academy?
Да. Каждый урок Pandas & NumPy Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Потоковое чтение CSV с chunksize
- Постепенное агрегирование по частям
- Введение в Dask DataFrames
- Parquet: быстрое столбцовое хранилище