Большие таблицы в pandas: память и типы данных
MemoryError при чтении файла — не приговор и не повод немедленно покупать память. Чаще всего таблица занимает в памяти в разы больше, чем на диске, потому что pandas хранит каждый столбец в типе по умолчанию.
Разберём, как оценить размер, уменьшить его и обработать данные, которые целиком не помещаются.
Почему памяти нужно больше, чем файлу
CSV хранит числа как текст: каждая цифра — байт. В памяти целое число занимает 8 байт, вещественное — тоже 8, строка — объект с накладными расходами.
К этому добавляются копии при операциях: фильтрация, слияние и сортировка создают промежуточные таблицы. Поэтому запас по памяти в два-три раза относительно «чистого» размера — разумная практика.
Оценка до загрузки
Прочитайте несколько первых строк и посмотрите на типы и ширину колонок. Затем прикиньте: число строк × число колонок × 8 байт — нижняя граница для числовых данных.
Для точной картины после загрузки используйте memory_usage(deep=True): без deep строковые колонки показываются неверно.
Типы данных
Самый быстрый выигрыш — понизить разрядность целых: int8, int16, int32 вместо int64, если диапазон значений позволяет. Для вещественных часто достаточно float32, но проверьте точность.
Строковые колонки с малым числом уникальных значений лучше перевести в категориальный тип: pandas хранит коды и словарь, а не повторяющиеся строки.
Категории и их ограничения
Категориальный тип ускоряет группировку и экономит память, но усложняет добавление новых значений: они должны попасть в категории.
Для колонок с тысячами уникальных значений выигрыш может быть нулевым или отрицательным. Проверяйте nunique() перед конвертацией.
Чтение по частям
Параметр chunksize позволяет читать файл блоками и агрегировать результат по мере обработки. Так можно посчитать сумму, среднее или число строк, не загружая файл целиком.
Ограничение: для операций, требующих всех данных сразу (сортировка, слияние больших таблиц), придётся либо увеличивать память, либо использовать другой инструмент.
Движок pyarrow и Parquet
pandas 2.0 добавил поддержку движка pyarrow для чтения CSV, а формат Parquet хранит данные в колончатом виде с типами и сжатием. Это уменьшает размер и ускоряет загрузку.
Parquet удобен как промежуточный формат: один раз преобразовали CSV и дальше читаете быстрее. Колончатое хранение позволяет читать только нужные столбцы.
Выбор колонок и фильтры
usecols при чтении отбрасывает лишние колонки сразу. Для больших файлов это часто даёт больше, чем любая оптимизация типов.
Фильтрацию по датам и категориям лучше делать на этапе чтения, если формат позволяет: меньше данных — меньше памяти.
Что делать, когда не помещается совсем
Варианты по возрастанию сложности: читать частями, использовать Parquet и выбирать столбцы, перейти на Dask или Polars, обрабатывать запросами к базе данных.
Выбор зависит от задачи. Для интерактивного анализа хватает первых двух шагов; для регулярной обработки больших объёмов лучше сразу смотреть в сторону колончатых форматов и распределённых инструментов.
Частые ошибки
- чтение всех колонок «на всякий случай»;
objectвместо категорий;float64для величин, где хватаетfloat32;- копии таблицы в цепочке операций;
- игнорирование
memory_usage(deep=True); - попытка отсортировать файл, который не помещается в память.
Пропуски и их тип
NaN в вещественной колонке и pd.NA в целочисленной ведут себя по-разному. При понижении типа до int8 пропуски не помещаются, и колонка останется вещественной.
Если пропусков мало, подумайте, нужны ли они вообще в анализе. Иногда корректнее удалить строки заранее, чем тащить nullable-типы через все операции.
Профилирование памяти по колонкам
memory_usage(deep=True) возвращает Series: отсортируйте её и начните с самой тяжёлой колонки. Обычно это строковый идентификатор или свободный текст.
Для текста рассмотрите хранение в отдельной таблице с ключом. Основная таблица останется компактной, а соединение выполнится только там, где текст действительно нужен.
Индексы и их цена
Индекс ускоряет поиск, но занимает память и пересчитывается при изменении таблицы. Для больших файлов сбрасывайте индекс, если он не нужен для выборок.
Мультииндекс удобен для группировки, однако после операций он часто остаётся «висящим» и мешает экспорту. Сбрасывайте его перед сохранением результата.
Чек-лист
- Размер оценён до загрузки.
- Прочитаны только нужные колонки.
- Типы понижены до разумных.
- Категории применены там, где это выгодно.
- Для больших файлов используется чтение частями.
- Промежуточный формат — Parquet.
- Проверена точность после смены типов.
Частые вопросы
Насколько помогает категориальный тип?
Зависит от числа уникальных значений. При десятках повторов строк выигрыш заметный, при почти уникальных значениях его нет.
Можно ли просто увеличить файл подкачки?
Технически да, но операции станут медленнее, а риск падения останется. Оптимизация типов даёт предсказуемый результат.
Что быстрее: pandas или Polars?
Для многих задач Polars быстрее и экономнее по памяти, но требует переписывания кода. Начинайте с оптимизации типов.
Как проверить, что данные не испортились?
Сравните контрольные суммы и агрегаты до и после преобразования: число строк, суммы, число пропусков.