Содержание
  1. CSV как текст, Parquet как типизированное хранение
  2. Полная CSV-строка с запятой, нулями и пропусками
  3. Один контракт типов для обоих форматов
  4. Пустая строка и null без соглашения
  5. Выбор столбцов и фильтрация: reader и статистики
  6. Матрица трёх сценариев выбора
  7. Проверка round trip и разбор ошибок
  8. Частые вопросы
Подборки и сравнения

Parquet или CSV: формат для таблиц и аналитики

13 ноября 2026 · 9 минут чтения

Parquet или CSV: формат для таблиц и аналитики — выбор сводится к природе данных. CSV остаётся текстовым соглашением: строки, разделители, правила кавычек. Parquet — типизированное колоночное хранение с описанием схемы внутри файла. Ниже — разбор одного учебного набора, контракт типов и матрица выбора.

CSV как текст, Parquet как типизированное хранение

Документация Apache Parquet описывает формат как открытый колоночный формат файлов, созданный для эффективного хранения и извлечения данных; он предоставляет схемы сжатия и кодирования для объёмных данных и поддерживается во многих языках и аналитических инструментах (https://parquet.apache.org/docs/overview/). Ключевое слово здесь — «колоночный»: значения одного столбца лежат рядом, что даёт читателю возможность запрашивать подмножество столбцов.

Документация Arrow по CSV описывает получение имён столбцов из первой строки и вывод типов при чтении (https://arrow.apache.org/docs/python/csv.html). Сам CSV содержит текст; типы определяются читателем по правилам или задаются явно.

Практическое следствие: CSV хранит символы, Parquet хранит значения вместе со схемой. Когда вы передаёте CSV коллеге, вы передаёте текст и договорённость о том, как этот текст читать. Когда вы сохраняете Parquet, схема едет внутри файла, и читатель получает её из метаданных.

Полная CSV-строка с запятой, нулями и пропусками

Возьмём условный учебный набор. Его значения заданы для разбора:

ТЕКСТ4 строки
order_id,amount,note
001,10.5,"a,b"
002,,
003,0,

Здесь три строки данных и три ловушки.

Первая — запятая внутри поля. У заказа 001 в note лежит a,b. Документация pandas по read_csv фиксирует правило: элементы в кавычках могут содержать разделитель, и он игнорируется (https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html). Без кавычек строка распалась бы на четыре поля, и парсер либо сдвинул бы столбцы, либо упал на несоответствии числа полей.

Вторая — ведущие нули. order_id записан как 001. Документация Arrow по CSV прямо разбирает этот случай: значения в кавычках всё равно проходят вывод типов, и чтобы сохранить форматирование вроде ведущих нулей, тип столбца задают явно как string (https://arrow.apache.org/docs/python/csv.html). При автоматическом выводе 001 станет числом 1, и обратная запись даст 1. Идентификатор заказа изменится.

Третья — пропуски. У заказа 002 пусты и amount, и note. У заказа 003 amount равен 0, а note пуст. В текстовом файле ,, и ,0, выглядят как обычные пустые поля.

Документация pandas добавляет: если keep_default_na равен False и na_values не заданы, ни одна строка не будет разобрана как NaN (https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html). Это рычаг управления, но он глобальный для чтения. Он не различает пустую строку и отсутствие значения — он решает, считать ли пустое поле пропуском вообще.

Один контракт типов для обоих форматов

Контракт исходной таблицы для нашего примера выглядит так:

Столбец Тип Правило
order_id string ведущие нули значимы, 001 остаётся 001
amount double, nullable число или отсутствие значения
note string, nullable текст, пустая строка или отсутствие значения

Этот контракт работает для обоих форматов. Разница в том, где он живёт. В Parquet он записывается в схему файла: order_id:string, amount:double nullable, note:string nullable. В CSV он живёт во внешнем документе, в коде читателя или в голове отправителя.

Для CSV документация Arrow предлагает column_types для типов столбцов и null_values для маркеров пропуска (https://arrow.apache.org/docs/python/csv.html). В pandas используются dtype, na_values и keep_default_na; указанные converters применяются вместо преобразования dtype (https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html).

Практический вывод: контракт типов пишется один раз и переносится в оба формата. Меняется носитель — схема файла или параметры читателя.

Пустая строка и null без соглашения

В нашем CSV у заказа 002 note пуст, и у заказа 003 note пуст. Символьно это одно и то же: между двумя запятыми ничего нет. Восстановить, где была пустая строка, а где отсутствие значения, из файла невозможно. Нужно внешнее соглашение.

В Parquet исходная схема различает эти случаи: значения note записаны как ["a,b", "", None]. Пустая строка и None — разные значения одного nullable-столбца.

Документация pandas по read_csv объясняет механику на стороне CSV: распознанные как отсутствующие значения читаются как NaN или NA-значение типа, независимо от указанного dtype (https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html). То есть по умолчанию пустое поле становится пропуском. Пустая строка как отдельное значение требует настройки: отключения стандартного набора пропусков через keep_default_na=False и явного перечисления того, что считать пропуском.

Отсюда два разных соглашения, и выбрать надо одно:

  1. Пустое поле означает отсутствие значения. Тогда пустая строка в данных неотличима от пропуска, и её нельзя сохранить в CSV без маркера.
  2. Пустое поле означает пустую строку. Тогда отсутствие значения кодируется отдельным маркером, например NULL или \N, и этот маркер перечисляется в na_values.

Документация Arrow даёт третий рычаг: strings_can_be_null и quoted_strings_can_be_null в ConvertOptions управляют тем, могут ли строковые и бинарные столбцы иметь пропуски и могут ли пропусками быть значения в кавычках (https://arrow.apache.org/docs/python/csv.html). Для такого различения в Arrow задайте null_values=[""], strings_can_be_null=True и quoted_strings_can_be_null=False: тогда "" сохраняется как пустая строка, а пустое поле без кавычек становится пропуском. Это соглашение, и его надо зафиксировать до обмена.

Выбор столбцов и фильтрация: reader и статистики

Колоночная раскладка даёт эффект только тогда, когда читатель умеет им пользоваться. Документация Arrow по Parquet формулирует прямо: можно передать подмножество столбцов для чтения, и это может быть существенно быстрее чтения всего файла благодаря колоночной раскладке (https://arrow.apache.org/docs/python/parquet/parquet.html). Там же отмечено ограничение: данные Parquet нужно декодировать из формата и распаковывать, поэтому напрямую с диска они не отображаются (https://arrow.apache.org/docs/python/parquet/parquet.html).

Фильтрация опирается на статистики. Документация Amazon Athena описывает predicate pushdown: в Parquet и ORC он позволяет запросам Athena выбирать только нужные блоки, улучшая производительность запроса (https://docs.aws.amazon.com/athena/latest/ug/columnar-storage.html). Это утверждение про Athena и про форматы Parquet и ORC в её контексте.

Для CSV аналогичные возможности зависят от читателя. Документация Arrow перечисляет include_columns — имена столбцов, включаемых в таблицу, и include_missing_columns, который при значении false вызывает ошибку, если столбец из include_columns отсутствует в CSV-файле (https://arrow.apache.org/docs/python/csv.html). Отбор столбцов на входе экономит память, но чтение всё равно проходит по строкам файла: чтобы добраться до нужного столбца, парсер разбирает всю строку.

Практическое правило: проверяйте возможности конкретного reader. Наличие параметра отбора столбцов в библиотеке не означает, что фильтрация по значениям дойдёт до уровня блоков файла.

Матрица трёх сценариев выбора

Сценарий Формат Что зафиксировать
Ручной обмен с человеком CSV контракт типов, правило кавычек, маркер пропуска
Повторная аналитика по части столбцов Parquet схему, подходящий reader, проверку nullable-типов
Получатель принимает только CSV CSV явную схему и согласованный маркер пропуска

Первый сценарий: файл открывают в таблице или редакторе. CSV читается глазами, Parquet требует инструмента. Отдавайте CSV вместе с описанием контракта: какие столбцы строковые, где допустимы пропуски, как кодируется отсутствие значения.

Второй сценарий: данные читаются многократно, а запросы затрагивают часть столбцов. Рассмотрите Parquet с подходящим reader и проверьте сохранение типов на одном полном цикле записи и чтения.

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

Проверка round trip и разбор ошибок

Две проверки в нашем примере независимы. Первая: ведущие нули в 001. Вторая: различие null и пустой строки. Даже если Parquet сохранил схему, нужно проверить перенос nullable-типов в целевой инструмент. Размеры файлов и скорость в этом разборе не измерялись.

Порядок проверки для обоих форматов:

  1. Запишите исходную таблицу с известными значениями: order_id со ведущими нулями, amount с числом и пропуском, note с текстом, пустой строкой и пропуском.
  2. Прочитайте файл тем же инструментом, которым будете читать в работе.
  3. Сравните order_id посимвольно. 001 совпадает с 001, 1 — расхождение.
  4. Сравните note по трём позициям: текст, пустая строка, пропуск. Совпадение по всем трём означает, что соглашение работает.
  5. Сравните amount: число сохранило значение, пропуск остался пропуском.

Частые причины расхождений. Автоматический вывод типов превращает 001 в 1 — лечится явным указанием строкового типа. Стандартный набор пропусков читает пустую строку как отсутствие значения — лечится настройкой na_values и keep_default_na. Читатель Parquet не поддерживает нужный логический тип — обзор Apache Parquet отмечает, что не все реализации поддерживают одни и те же возможности формата, и при интеграции нескольких реализаций важно проверять совместимость и производительность (https://parquet.apache.org/docs/overview/).

Частые вопросы

Parquet или CSV: что быстрее читается?

Скорость зависит от читателя, данных и выбранных столбцов. Документация Arrow указывает, что отбор части столбцов Parquet может ускорить чтение. Для выбора сравните одинаковую задачу на своих файлах и зафиксируйте условия измерения.

Почему из CSV пропадают ведущие нули?

Автоматический вывод типов может прочитать 001 как число. Явно задайте строковый тип order_id, затем проверьте значения после чтения и обратной записи. Одних кавычек вокруг идентификатора недостаточно.

Как отличить пустую строку от пропуска в CSV?

Задайте отдельный маркер пропуска и согласуйте параметры na_values и keep_default_na. Пустая строка и пропуск должны иметь разные представления; проверьте оба случая после обратного чтения.

Parquet сжимает файлы сильнее CSV?

Итоговый размер зависит от данных, схемы, кодирования и алгоритма сжатия. CSV тоже можно передавать в сжатом потоке. Выберите поддерживаемый получателем вариант и сравните размеры на своём наборе.

Можно ли читать только нужные столбцы из Parquet?

Да, если reader поддерживает выбор столбцов при чтении. Проверяйте эту возможность отдельно от фильтрации строк по значениям: для неё важны predicate pushdown и подходящие метаданные файла.

Читайте также

3 материала