Улучшение потребления памяти и скорости

Если вы специалист по данным, вы, вероятно, использовали Pandas для обработки табличных данных, применения матричных операций к строкам или столбцам, выполнения сложных слияний между фреймами данных, построения временных рядов, вычисления агрегатов и т. Д.

Pandas - отличный, быстрый и надежный инструмент, который никогда не должен покидать ваш ящик с инструментами.

Однако, если вы интенсивно пользуетесь Pandas, вы, вероятно, сталкивались с некоторыми проблемами, связанными с медленным выполнением или ограничениями нехватки памяти.

В этой статье я поделюсь с вами тремя советами по дальнейшей оптимизации рабочего процесса Pandas. Я применял эти советы в последнее время во время проекта, который включал очень большой набор данных, и это мне очень помогло.

Давайте сразу же приступим.

1. Уменьшите потребление памяти фреймами данных

Панды могут обрабатывать столбцы разных типов:

  • object - строковые или смешанные типы (в основном, все нестандартное)
  • string - начиная с Pandas 1.0.0
  • int - целое число
  • float - числа с плавающей запятой
  • bool - логические значения True и False
  • datetime— значения даты и времени
  • timedelta - разница во времени между двумя datetimeсек.
  • category - ограниченный список значений, сохраненных как поиск с эффективным использованием памяти

Погодите, в чем разница между int16, int32 и int64?

Это все типы целых чисел со знаком. Разница заключается в емкости каждого из них.

int16 позволяет использовать целые числа, попадающие в интервал [-32,768, +32,767], а int32 позволяет использовать целые числа в интервале от [2 147 483 648 до +2 147 483 647].

Хорошо, а как насчет float32 и float64?

float32 - 32-битное число — float64 использует 64 бита.

Это означает, что float64 занимает вдвое больше памяти - и выполнение операций с ним может быть намного медленнее в некоторых архитектурах машин.
Однако float64s может представлять числа гораздо точнее, чем 32-битные числа с плавающей запятой.

Проблема с Pandas: если вы позволите Pandas автоматически определять типы ваших столбцов, например, из файла CSV, он хорошо справится с угадыванием разницы между числами с плавающей запятой, целыми числами и объектами. Но будет ли это предположение оптимальным с точки зрения памяти? Не всегда.

Зачем, например, использовать тип int32 для одного из столбцов, если его значения лежат в интервале [-32,768, +32,767]? И зачем вам использовать тип float64, если вам нужна только точность от двух до трех десятичных знаков?

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

Эта функция часто используется в ядрах Kaggle. (Я выбрал реализацию по этой ссылке на Kaggle).

Это очень полезно. На большом фрейме данных, над которым я работал в последнее время (32 миллиона строк и 10 числовых столбцов), эта функция освобождает до 700 МБ ОЗУ!

2. Параллельное выполнение Pandas с помощью pandarallel

Если вы выполняете трудоемкие операции со своими данными, вы можете использовать несколько ядер вашей рабочей станции и использовать Pandarallel для распараллеливания Pandas.

Конечно, есть и другие решения, такие как Dask или Modin, которые можно попробовать для ускорения работы Pandas. Я считаю, что Pandarallel очень прост в использовании, потому что он не заставляет вас изучать новый синтаксис / фреймворк.

Вы можете установить Pandarallel с помощью pip:

pip install pandarallel

И вместо использования стандартного метода apply, например:

вы бы использовали метод parallel_apply:

Вот сравнение между Pandas и Pandarallel.

Небольшое предупреждение: если вы используете Pandarallel для большого фрейма данных, параллельное выполнение не произойдет мгновенно. Из-за копирования данных между несколькими ядрами можно ожидать дополнительных затрат времени.

3. Прекратите экспорт данных в CSV.

Мы все использовали CSV. Он удобочитаемый, его можно редактировать в любой среде IDE, и каждый может открыть его с любой платформы. Однако манипулирование CSV-файлами в Pandas также имеет ряд недостатков:

  • Он использует много места на диске.
  • Медленно читать и писать. (Экспорт большого фрейма данных с 32 миллионами строк занял у меня около 60 секунд.)
  • Он не хранит типы столбцов.

Чтобы преодолеть эти проблемы, я недавно начал использовать форматы Parquet для сериализации моих фреймов данных.

Apache Parquet - это бесплатный формат хранения данных с открытым исходным кодом, ориентированный на столбцы, в экосистеме Apache Hadoop. Он похож на другие форматы файлов столбчатого хранения, доступные в Hadoop, а именно RCFile и ORC. Он совместим с большинством фреймворков обработки данных в среде Hadoop. Он обеспечивает эффективные схемы сжатия и кодирования данных с повышенной производительностью для обработки больших объемов сложных данных ». - Википедия

Формат паркета имеет множество преимуществ перед CSV:

  • Это быстрее. (Начиная с десяти рядов пиарроу примерно в пять раз быстрее.)
  • Полученный файл меньше (~ 50% CSV).
  • Он хранит информацию о типах данных.
  • Он имеет широкую поддержку в экосистеме Hadoop, что позволяет быстро фильтровать множество разделов.

Заключение

Есть много других способов ускорить работу Pandas и улучшить рабочий процесс. Я нашел эти статьи интересными, если вы хотите больше вникнуть в тему:

Если вы знаете другие полезные трюки Pandas, дайте мне знать в комментариях.

использованная литература

Https://stackoverflow.com/questions/9696660/what-is-the-difference-between-int-int16-int32-and-int64

Https://stackoverflow.com/questions/43440821/the-real-difference-between-float32-and-float64



Впервые на Medium? Вы можете подписаться за 5 долларов в месяц и разблокировать неограниченное количество статей - нажмите здесь.