Улучшение потребления памяти и скорости
Если вы специалист по данным, вы, вероятно, использовали Pandas для обработки табличных данных, применения матричных операций к строкам или столбцам, выполнения сложных слияний между фреймами данных, построения временных рядов, вычисления агрегатов и т. Д.
Pandas - отличный, быстрый и надежный инструмент, который никогда не должен покидать ваш ящик с инструментами.
Однако, если вы интенсивно пользуетесь Pandas, вы, вероятно, сталкивались с некоторыми проблемами, связанными с медленным выполнением или ограничениями нехватки памяти.
В этой статье я поделюсь с вами тремя советами по дальнейшей оптимизации рабочего процесса Pandas. Я применял эти советы в последнее время во время проекта, который включал очень большой набор данных, и это мне очень помогло.
Давайте сразу же приступим.
1. Уменьшите потребление памяти фреймами данных
Панды могут обрабатывать столбцы разных типов:
object
- строковые или смешанные типы (в основном, все нестандартное)string
- начиная с Pandas 1.0.0int
- целое число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
занимает вдвое больше памяти - и выполнение операций с ним может быть намного медленнее в некоторых архитектурах машин.
Однако float64
s может представлять числа гораздо точнее, чем 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 и улучшить рабочий процесс. Я нашел эти статьи интересными, если вы хотите больше вникнуть в тему:
- Https://realpython.com/python-pandas-tricks/
- Https://towardsdatascience.com/4-pandas-tricks-that-most-people-dont-know-86a70a007993
Если вы знаете другие полезные трюки 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