Лучший формат данных для хранения pandas.DataFrame
На сегодняшний день существует огромное количество форматов для хранения данных, и, используя библиотеку Pandas при обработке большого объёма данных, возникает вопрос – а какой формат, с которыми Pandas работает «из коробки», даст наибольшую производительность, при дальнейшем использовании, обработанного DataFrame?
Ремарка: поиск информации по этой теме, привёл меня к репозиторию, за авторством Devforfu (ссылка), но так как информация в нём датируется 2019 годом, а за этот период вышло множество обновлений, я решил написать «свежий» бенчмарк, основываясь на принципах автора – ссылка на обновленный бенчмарк. Отмечу, что из-за слишком большой разницы в полученных результатах, я склоняюсь к тому, что мог совершить ошибку, поэтому далее в статье будет указана информация по оригиналу.
В качестве тестируемых форматов использовались следующие варианты: CSV (как самый популярный текстовый формат), Pickle, Feather, Parquet, Msgpack, HDF. Для сравнения будем использовать следующие метрики: размер сериализованного файла, время загрузки DataFrame из файла, время сохранения DataFrame в файл, потребление оперативной памяти при сохранении и загрузке DataFrame.
Тестовые данные – сгенерированный DataFrame с 1 миллионом строк, 15 столбцами цифр и 15 столбцами строковых значений. Генерация численных данных проводилась с помощью numpy. random.normal, в качестве строчных данных использовались UUID. С появлением в Pandas, категориального типа данных (Categorical data), который использует гораздо меньше памяти и более производительней в обработке (обширный материал для другой статьи), интересно также сравнить насколько изменится производительность форматов, поэтому ещё одним этапом сравнения в тестовых данных стал перевод формата «object» к формату «category».
Бенчмарк
Метрики собирались в течении 20 раундов, после чего группировались в результирующий DataFrame по среднему значению. Посмотрим на результаты:




Результаты:
- Лидером по скорости сохранения и загрузки является Parquet, за ним на втором месте Feather, аутсайдером выступил формат CSV.
- По росту потребления памяти лидирует текстовый формат CVS, хорошая дельта во время загрузки файла у Msgpack, но высокая при сохранении, поэтому второе место занимает Feather, а на третьем месте Parquet.
- По размеру сериализованного файла, с огромным отрывом побеждает Parquet.
Далее, посмотрим на результаты с категориальным типом данных:


Так как CSV, на фоне остальных, сильно проигрывает, приведём график без него, для наглядности.



Результаты:
- Лидер по скорости изменился и им стал Feather, за ним на втором месте Pickle.
- По росту потребления памяти также есть изменения: на первом месте feather, второе делят между собой Pickle/Msgpack и аутсайдером при загрузке файла выступил Parquet.
- По размеру сериализованного файла, у Parquet уже нет безоговорочного лидерства.
Файл или База данных?
Получив данные по форматам, стало интересно сравнение производительности с базами данных (далее по тексту – БД). Тут нужно учесть, что основное преимущество хранения в БД — это конкурентный доступ. В случаях, когда он не требуется, хранение данных в файлах обеспечит более прямой и очевидный доступ.
Такое сравнение, с использованием Microsoft SQL Server, привелось в статье – architecture-performance. Краткая выжимка результатов: по скорости чтения БД отстаёт от файлового хранения, а самым быстрым драйвером является Turbodbc.

Итоги
Так как, в одной из первых строк документации Pickle, указано предупреждение о том, что формат небезопасен, можно выделить двух лидеров бенчмарка: Feather и Parquet.

Если в DataFrame не используется категориальный тип данных Pandas, то для долгосрочного хранения больших данных, лучше всего подойдёт формат «Parquet», за счёт минимального размера сериализованного файла. В остальных случаях, формат «Feather» будет самым оптимальным вариантом и позволит с большей скоростью обрабатывать данные, потребляя при этом меньше ресурсов.