Автор оригинала: Guido Tournois.
Автор Гвидо Турнуа , специалист по обработке данных в АЭРОПОРТУ |/Vantage
Каждый специалист по обработке данных знает, что предварительная обработка данных и разработка функций имеют первостепенное значение для успешного проекта в области науки о данных. Однако часто эти шаги отнимают много времени и заставляют вас ждать завершения вычислений, что мешает вам создать эту потрясающую модель. В этом посте мы рассмотрим несколько трюков, которые помогут ускорить рабочие процессы обработки данных pandas, позволяя пандам оптимально использовать вашу машину.
Pandas-это мощная, универсальная и простая в использовании библиотека Python для управления структурами данных. Для многих специалистов по обработке данных, таких как я, он стал основным инструментом, когда дело доходит до изучения и предварительной обработки данных, а также для разработки лучших функций прогнозирования. Несмотря на то, что Pandas все еще быстро совершенствуется, мы видим, что пользователи Pandas возвращаются к альтернативным инструментам, таким как Spark, поскольку наборы данных становятся слишком большими, чтобы поместиться в оперативной памяти. К сожалению, вам приходится учиться и использовать другой инструмент только потому, что у вас слишком много данных. Поэтому я рассмотрел четыре стратегии для обработки этих слишком больших наборов данных, не выходя из комфорта Панд:
- Отбор проб
- Разбиение на куски
- Оптимизация типов панд
- Параллелизация панд с Даском
Отбор проб Самый простой вариант-это выборка набора данных. Этот подход может быть особенно эффективным на этапе исследования: как выглядят данные? Какие функции я могу создать? Другими словами, что работает, а что нет. Часто случайная выборка из 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 автоматически выводит типы данных. Очень удобно, конечно, однако часто эти типы данных не являются оптимальными и занимают больше памяти, чем необходимо. Мы рассмотрим три наиболее распространенных типа данных, используемых пандами — int, float и object — и покажем, как уменьшить их отпечаток памяти, рассматривая пример.
По умолчанию Pandas устанавливает тип целых чисел в int64, этот тип данных занимает 8 байт и может представлять огромные целые числа, от -9223372036854775808 до 9223372036854775807. Однако во многих случаях целые числа представляют собой счетные объекты, такие как количество автомобилей или посетителей в день. Эти типы чисел могут быть легко представлены в четыре раза меньшем dtype int16. Если ваши данные соответствуют диапазону от -32768 до 32767, преобразуйте их в int16, чтобы добиться сокращения памяти на 75%! В случае, если ваши данные положительные и ниже 65535, перейдите к варианту без знака, uint16.
Точно так же класс float состоит из float16, float32 и float64, где последний является значением по умолчанию для Pandas. Float64 может представлять как очень маленькие, так и большие числа с высокой точностью, что делает его пригодным для точных вычислений. Однако часто вы обнаруживаете, что работаете с уже зашумленными данными, такими как данные датчиков или данные с ограниченной точностью от самого себя, такие как валюта. Опять же, меньшие типы данных float32 или float 16 будут служить целям многих вариантов использования и уменьшат ваш отпечаток памяти на 50%, соответственно на 75%.
Еще один способ резко уменьшить размер фрейма данных Pandas-преобразовать столбцы типа Object в категорию. Вместо того, чтобы иметь копии одной и той же строки во многих позициях в вашем фрейме данных, панды будут иметь одну копию из каждой строки и будут использовать указатели под капотом, которые ссылаются на эти строки. Однако обратите внимание, что если каждая строка имеет другую строку, этот подход не будет работать.
В приведенном ниже блокноте я демонстрирую уменьшение отпечатка памяти фрейма данных с 88,4%, только изменив типы данных. Нажмите здесь, чтобы увидеть записную книжку юпитера
Dask Dataframe Еще один способ обработки больших фреймов данных-это использование того факта, что наша машина имеет более одного ядра. Для этой цели мы использовали ask, проект python с открытым исходным кодом, который распараллеливает Numpy и Pandas. Под капотом фрейм данных Dask состоит из множества фреймов данных Pandas, которые обрабатываются параллельно. Поскольку большинство API Pandas реализовано, диск имеет очень похожий внешний вид, что делает его простым в использовании для всех, кто знает Панд.
Под капотом фрейм данных Dask состоит из множества фреймов данных pandas
Возникает вопрос, как данные, которые не помещаются в память при использовании Pandas, могут помещаться в память при использовании Dask. Ответ заключается в том, что фрейм данных и операции Dask являются ленивыми. Это означает, что операции выполняются не сразу, а скорее создают график задач. Мы можем интерпретировать этот график как рецепт для вычисления результата. При вызове метода вычислений встроенный планировщик настольных задач координирует частичную загрузку и обработку данных, используя при этом все ядра. Как только все промежуточные результаты вычислены, Dask объединяет их и возвращает конечный результат.
Это искусство? Возможно, это задачи, выполняющие различные задачи параллельно на моей машине с 6 ядрами (12 потоков).
Не вдаваясь в подробности, рассмотрим ссылку ниже, в которой я проведу некоторую обработку данных по набору данных New York Yellow Taxi 2015 года. Он состоит из 12 файлов .csv объемом около 2 ГБ каждый. Чтобы иметь справедливое сравнение, я проделал те же шаги обработки и в Панд. Поскольку полный набор данных не помещается в память, мой ноутбук интенсивно использовал пространство подкачки и сжатие памяти, чтобы заставить его работать.
Нажмите здесь, чтобы увидеть записную книжку юпитера
В приведенном выше блокноте мы выполнили некоторые задачи по манипулированию данными с довольно большим набором данных, используя как Pandas, так и Dask. Мы видим, что общее время работы для панд составляет 19 минут, в то время как для стола потребовалось всего 10 минут, что почти вдвое быстрее. Более того, как и было обещано, синтаксис и функции, используемые Dask, соответствуют почти 1-на-1 пандам, что делает написание рабочего процесса Dask по существу тривиальным, если вы знаете своих Панд.
Заключение В этом посте я показал, что не все потеряно, когда ваш набор данных слишком велик, и вы настаиваете на использовании панд. В зависимости от вашей цели вы можете преодолеть проблемы с памятью, применив одну из описанных стратегий. Для целей исследования вам лучше всего использовать выборку ваших данных. В случае, если вам нужно обработать все ваши данные, попробуйте выполнить итерацию данных или оптимизировать типы данных. Является ли ваш набор данных все еще слишком большим, и вы устали получать кофе каждый раз, когда ваши вычисления выполняются, а затем перейдите к Dask, чтобы распараллелить панд.
Об авторе Гвидо Турнуа является специалистом по обработке данных в Vantage AI, консалтинговой компании по обработке данных в Нидерландах. Если вам нужна помощь в создании моделей машинного обучения для ваших данных, не стесняйтесь обращаться к нам по адресу info@vantage-ai.com .