Исследователям данных часто приходится работать с достаточно объемными наборами данных, которые трудно обработать компьютеру. Эта проблема не нова и, как и любая другая, не имеет универсального решения. Лучший выход из положения будет зависеть от конкретных данных и задач приложения. И все же попытаемся выделить из три наиболее оптимальных решения.
1. Сокращение используемой памяти путем оптимизации типов данных
При загрузке данных с использованием Pandas типы определяются автоматически (если не указана иная задача). В большинстве случаев этот подход работает отлично, но выводимый тип не обязательно будет оптимизирован. Более того, если числовой столбец содержит отсутствующие значения, то автоматически вычисляемый тип будет float
.
Недавно я использовала этот метод для анализа в основном целочисленных типов данных, представляющих годы, месяцы и дни:
В данном случае определение типов данных привело к значительному сокращению используемой памяти. Обратите внимание, что в приведенном примере с помощью pandas.Int16Dtype я принудительно определила тип int
для столбца, содержащего отсутствующие значения. Это достигается внутренним использованием pandas.NA, вместо numpy.nan, для недостающих значений.
Оптимизация типов данных при работе с наборами больших данных требует предварительного изучения. Вряд ли этот способ окажется полезным на исследовательской фазе обработки неизвестного набора.
2. Разделение данных на фрагменты
Когда данные слишком велики, чтобы поместиться в памяти, можно воспользоваться опцией Pandas chunksize
. Она позволяет разделить данные на фрагменты вместо того, чтобы работать с одним большим блоком. При использовании этой опции создается объект-итератор, с помощью которого можно просматривать различные фрагменты и выполнять фильтрацию или анализ точно так же, как при загрузке полного набора данных.
Вот пример использования этой опции для просмотра набора данных обзоров Yelp, извлечения данных о минимальном и максимальном времени обзоров в каждом блоке, а затем установления полного временного интервала, потребовавшегося для обзоров:
reader = pd.read_json(reviews_path, lines=True, orient = "records", chunksize = 100000)
# прохождение по блокам и извлечение мин./макс. времени
date_limits = []
for chunk in reader:
date_limits.append(max(chunk.date))
date_limits.append(min(chunk.date))
print("Reviews span from {} to {}".format(min(date_limits).strftime('%d-%m-%Y'),
max(date_limits).strftime('%d-%m-%Y')))
Этот метод может применяться на всем пути работы с данными — от предварительного эксплораторного анализа до обучения модели. При этом потребуется минимум дополнительных настроек.
3. Использование преимуществ ленивых вычислений
Ленивые вычисления относятся к стратегиям, позволяющим отложить операцию вычисления до того момента, когда возникнет реальная необходимость в результате. Ленивые вычисления — важная концепция, особенно полезная для функционального программирования.
На основе ленивых вычислений построены такие механизмы распределенных вычислений, как Spark и Dask. Они предназначены для работы с кластерами, но пригодятся и для обработки больших массивов данных на компьютере.
В отличие от Pandas, они не загружают данные непосредственно в память. Вместо этого, во время чтения происходит сканирование данных, вывод их типов и разбиение их на разделы. Вычислительные графы для этих разделов строятся независимо и выполняются только тогда, когда это действительно необходимо (отсюда и название “ленивые вычисления”).
Pyspark используется для выполнения эксплораторного анализа набора данных, превышающих объем памяти компьютера. Dask также довольно популярен, примеры его применения найти несложно. Синтаксис Dask имитирует синтаксис Pandas, так что он будет выглядеть очень знакомым. Однако, если Dask ограничен использованием Python, то Spark также будет работать с Java и Scala.
Аналогичные возможности предлагают такие библиотеки, как Vaex и Modin.
Читайте также:
- 6 функций Pandas для быстрого эксплораторного анализа данных
- Нет жесткому кодированию конфиденциальных данных в приложениях Python!
- Как создать бота для автоматизации повседневных задач, с помощью Python и Google BigQuery
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Georgia Deaconu: 3 ways to deal with large datasets in Python