4 стратегии работы с большими наборами данных с использованием Pandas

По Турниры Гвидоспециалист по данным в Преимущество ИИ

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

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

  • Выборка
  • Чанкинг
  • Оптимизация dtypes Pandas
  • Распараллеливание Pandas с Dask

Выборка
Самый простой вариант — выборка вашего набора данных. Этот подход может быть особенно эффективным на этапе исследования: как выглядят данные? Какие функции я могу создать? Другими словами, что работает, а что нет. Часто случайная выборка из 10% такого большого набора данных уже будет содержать много информации. Это поднимает первый вопрос: действительно ли вам нужно обрабатывать весь набор данных для обучения адекватной модели?

import pandas
import random

filename = "data.csv" 
n = sum(1 for line in open(filename))-1  # Calculate number of rows in file
s = n//10  # sample size of 10%
skip = sorted(random.sample(range(1, n+1), n-s))  # n+1 to compensate for header 
df = pandas.read_csv(filename, skiprows=skip)

Чанки / Итерация
Если вам нужно обработать все данные, вы можете разделить данные на несколько фрагментов (которые сами по себе помещаются в памяти) и выполнить очистку данных и разработку функций для каждого отдельного фрагмента. Более того, в зависимости от типа модели, которую вы хотите использовать, у вас есть два варианта:

  • Если выбранная вами модель допускает частичную подгонку, вы можете постепенно обучать модель на данных каждого фрагмента;
  • Обучите модель на каждом отдельном фрагменте. Впоследствии, чтобы оценить новые невидимые данные, сделайте прогноз с каждой моделью и примите среднее или большинство голосов в качестве окончательного прогноза.
import pandas
from sklearn.linear_model import LogisticRegression
datafile = "data.csv"
chunksize = 100000
models = []
for chunk in pd.read_csv(datafile, chunksize=chunksize):
    chunk = pre_process_and_feature_engineer(chunk) 
    # A function to clean my data and create my features
    model = LogisticRegression()
    model.fit(chunk[features], chunk['label'])
    models.append(model)
df = pd.read_csv("data_to_score.csv")
df = pre_process_and_feature_engineer(df)
predictions = mean([model.predict(df[features]) for model in models], axis=0)

Оптимизация типов данных
При загрузке данных из файла Pandas автоматически определяет типы данных. Очень удобно конечно, однако часто эти типы данных не оптимальны и занимают больше памяти, чем нужно. Мы рассмотрим три наиболее распространенных типа данных, используемых Pandas — int, float и object — и покажем, как уменьшить их отпечаток в памяти на примере.

По умолчанию Pandas устанавливает dtype целых чисел в int64, этот тип данных занимает 8 байт и может представлять огромные целые числа, от -9223372036854775808 до 9223372036854775807. Однако часто целые числа представляют собой исчисляемые объекты, такие как количество автомобилей или посетителей в день. Эти типы чисел могут быть легко представлены в четыре раза меньшем dtypeint16. Если ваши данные находятся в диапазоне от -32768 до 32767, преобразуйте их в int16, чтобы добиться сокращения памяти на 75%! Если ваши данные положительны и ниже 65535, выберите вариант без знака, uint16.

Точно так же класс float состоит из float16, float32 и float64, где последний используется Pandas по умолчанию. Float64 может представлять как очень маленькие, так и большие числа с высокой точностью, что делает его подходящим для точных вычислений. Однако часто приходится работать с уже зашумленными данными, такими как данные датчиков или данные с ограниченной точностью относительно самих себя, например валюта. Опять же, меньшие типы данных float32 или float16 будут служить многим целям использования и уменьшат отпечаток памяти на 50% или 75% соответственно.

Еще один способ резко уменьшить размер вашего фрейма данных Pandas — преобразовать столбцы объекта dtype в категорию. Вместо того, чтобы иметь копии одной и той же строки во многих позициях вашего фрейма данных, панды будут иметь одну копию из каждой строки и будут использовать под капотом указатели, которые ссылаются на эти строки. Однако обратите внимание, что если каждая строка имеет другую строку, этот подход не будет работать.

В приведенной ниже записной книжке я демонстрирую снижение отпечатка памяти фрейма данных с 88,4% только за счет изменения типов данных.
Нажмите здесь, чтобы увидеть Jupter Notebook

Dask Dataframe
Другой способ обработки больших фреймов данных — использовать тот факт, что наша машина имеет более одного ядра. Для этой цели мы используем Dask, проект Python с открытым исходным кодом, который распараллеливает Numpy и Pandas. Под капотом Dask Dataframe состоит из множества фреймов данных Pandas, которые обрабатываются параллельно. Поскольку большая часть API Pandas реализована, Dask имеет очень похожий внешний вид, что упрощает его использование для всех, кто знаком с Pandas.

1*q6sALf9exENmQFmrFd-W9A.png
Под капотом Dask Dataframe состоит из множества pandas DataFrames.

Возникает вопрос, как данные, которые не помещаются в памяти при использовании Pandas, помещаются в память при использовании Dask. Ответ заключается в том, что Dask Dataframes и операции ленивы. Это означает, что операции выполняются не сразу, а строят граф задач. Мы можем интерпретировать этот график как рецепт вычисления результата. При вызове метода вычисления встроенный планировщик задач Dask координирует частичную загрузку и обработку данных, используя все ядра. Как только все промежуточные результаты вычислены, Dask объединяет их и возвращает окончательный результат.

1*NXx5YaZ7EDQeLLycdulyeA.png
Это искусство? Возможно, это Dask, выполняющий множество задач параллельно на моей машине с 6 ядрами (12 потоков).

Не вдаваясь в подробности, рассмотрим ссылку ниже, в которой я проведу некоторую обработку данных из набора данных New York Yellow Taxi 2015 года. Он состоит из 12 файлов .csv размером около 2 ГБ каждый. Для честного сравнения я проделал те же шаги обработки и в Pandas. Поскольку полный набор данных не помещается в память, мой ноутбук интенсивно использовал пространство подкачки и сжатие памяти, чтобы заставить его работать.

Нажмите здесь, чтобы увидеть Jupter Notebook

В приведенном выше блокноте мы выполнили некоторые задачи по обработке данных в довольно большом наборе данных, используя как Pandas, так и Dask. Мы видим, что общее время выполнения для Pandas составляет 19 минут, тогда как для Dask это заняло всего 10 минут, что делает его почти в два раза быстрее. Более того, как и было обещано, синтаксис и функции, используемые Dask, почти полностью совпадают с Pandas, что упрощает написание рабочего процесса Dask, если вы знаете Pandas.

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

Об авторе
Турниры Гвидо работает специалистом по данным в Vantage AI, консалтинговой компании по обработке данных в Нидерландах. Если вам нужна помощь в создании моделей машинного обучения для ваших данных, не стесняйтесь обращаться к нам по адресу info@vantage-ai.com.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *