- PVSM.RU - https://www.pvsm.ru -
«Пять экзабайт информации создано человечеством с момента зарождения цивилизации до 2003 года, но столько же сейчас создаётся каждые два дня». Эрик Шмидт
Datatable — это Python-библиотека для выполнения эффективной многопоточной обработки данных. Datatable поддерживает наборы данных, которые не помещаются в памяти.
Если вы пишете на R, то вы, вероятно, уже используете пакет data.table
. Data.table [1] — это расширение R-пакета data.frame [2]. Кроме того, без этого пакета не обойтись тем, кто пользуется R для быстрой агрегации больших наборов данных (речь идёт, в частности, о 100 Гб данных в RAM).
Пакет data.table
для R весьма гибок и производителен. Пользоваться им легко и удобно, программы, в которых он применяется, пишутся довольно быстро. Этот пакет широко известен в кругах R-программистов. Его загружают более 400 тысяч раз в месяц, он используется в почти 650 CRAN и Bioconductor-пакетах (источник [3]).
Какая от всего этого польза для тех, кто занимается анализом данных на Python? Всё дело в том, что существует Python-пакет datatable
, являющийся аналогом data.table
из мира R. Пакет datatable
чётко ориентирован на обработку больших наборов данных. Он отличается высокой производительностью — как при работе с данными, которые полностью помещаются в оперативной памяти, так и при работе с данными, размер которых превышает объём доступной RAM. Он поддерживает и многопоточную обработку данных. В целом, пакет datatable [4] вполне можно назвать младшим братом data.table [5].
Современным системам машинного обучения нужно обрабатывать чудовищные объёмы данных и генерировать множество признаков. Это нужно для построения как можно более точных моделей. Python-модуль datatable
был создан для решения этой проблемы. Это — набор инструментов для выполнения операций с большими (до 100 Гб) объёмами данных на одиночном компьютере на максимально возможной скорости. Спонсором разработки datatable
является H2O.ai [6], а первым пользователем пакета — Driverless.ai [7].
Этот набор инструментов очень напоминает pandas [8], но он сильнее ориентирован на обеспечение высокой скорости обработки данных и на поддержку больших наборов данных. Разработчики пакета datatable
, кроме того, стремятся к тому, чтобы пользователям было бы удобно с ним работать. Речь идёт, в частности, о мощном API и о продуманных сообщениях об ошибках. В этом материале мы поговорим о том, как пользоваться datatable
, и о том, как он выглядит в сравнении с pandas
при обработке больших наборов данных.
В MacOS datatable
можно легко установить с помощью pip
:
pip install datatable
В Linux установка производится из бинарных дистрибутивов:
# Для Python 3.5
pip install https://s3.amazonaws.com/h2o-release/datatable/stable/datatable-0.8.0/datatable-0.8.0-cp35-cp35m-linux_x86_64.whl
# Для Python 3.6
pip install https://s3.amazonaws.com/h2o-release/datatable/stable/datatable-0.8.0/datatable-0.8.0-cp36-cp36m-linux_x86_64.whl
В настоящий момент datatable
не работает под Windows, но сейчас ведётся работа в этом направлении, так что поддержка Windows — это лишь вопрос времени.
Подробности об установке datatable
можно найти здесь [9].
Код, который будет использован в этом материале, можно найти в этом [10] GitHub-репозитории или здесь [11], на mybinder.org.
Набор данных, с которым мы тут будем экспериментировать, взят с Kaggle (Lending Club Loan Data Dataset [12]). Этот набор состоит из полных данных обо всех займах, выданных в 2007-2015 годах, включая текущее состояние займа (Current, Late, Fully Paid и так далее) и самые свежие сведения о платеже. Файл состоит из 2.26 миллиона строк и 145 столбцов. Размер этого набора данных идеально подходит для демонстрации возможностей библиотеки datatable
.
# Импортируем необходимые библиотеки
import numpy as np
import pandas as pd
import datatable as dt
Давайте загрузим данные в объект Frame
. Базовая единица анализа в datatable
— это Frame
. Это — то же самое, что DataFrame
из pandas
или SQL-таблица. А именно, речь идёт о данных, организованных в виде двумерного массива, в котором можно выделить строки и столбцы.
%%time
datatable_df = dt.fread("data.csv")
____________________________________________________________________
CPU times: user 30 s, sys: 3.39 s, total: 33.4 s
Wall time: 23.6 s
Вышеприведённая функция fread()
представляет собой мощный и очень быстрый механизм. Она может автоматически обнаруживать и обрабатывать параметры для подавляющего большинства текстовых файлов, загружать данные из .ZIP-архивов и из Excel-файлов, получать данные по URL и делать многое другое.
Кроме этого, парсер datatable
обладает следующими возможностями:
Теперь посмотрим — сколько времени нужно pandas
на то, чтобы прочитать тот же самый файл.
%%time
pandas_df= pd.read_csv("data.csv")
___________________________________________________________
CPU times: user 47.5 s, sys: 12.1 s, total: 59.6 s
Wall time: 1min 4s
Можно видеть, что datatable
явно работает быстрее pandas
при чтении больших наборов данных. Pandas
в нашем эксперименте нужно больше минуты, а время, необходимое datatable
, измеряется секундами.
Существующий объект Frame
пакета datatable
можно конвертировать в объект DataFrame
numpy
или pandas
. Делается это так:
numpy_df = datatable_df.to_numpy()
pandas_df = datatable_df.to_pandas()
Попробуем преобразовать существующий объект Frame
datatable
в объект DataFrame
pandas
и посмотрим на то, сколько это займёт времени.
%%time
datatable_pandas = datatable_df.to_pandas()
___________________________________________________________________
CPU times: user 17.1 s, sys: 4 s, total: 21.1 s
Wall time: 21.4 s
Похоже, что чтение файла в объект Frame
datatable
и последующее преобразование этого объекта в объект DataFrame
pandas
занимает меньше времени, чем загрузка данных в DataFrame
средствами pandas
. Поэтому, возможно, если планируется обрабатывать большие объёмы данных с помощью pandas
, лучше будет загружать их средствами datatable
, а потом уже преобразовывать в DataFrame
.
type(datatable_pandas)
___________________________________________________________________
pandas.core.frame.DataFrame
Рассмотрим основные свойства объекта Frame
из datatable
. Они очень похожи на аналогичные свойства объекта DataFrame
из pandas
:
print(datatable_df.shape) # (количество строк, количество столбцов)
print(datatable_df.names[:5]) # имена первых 5 столбцов
print(datatable_df.stypes[:5]) # типы первых 5 столбцов
______________________________________________________________
(2260668, 145)
('id', 'member_id', 'loan_amnt', 'funded_amnt', 'funded_amnt_inv')
(stype.bool8, stype.bool8, stype.int32, stype.int32, stype.float64)
Тут нам доступен и метод head()
, выводящий n
первых строк:
datatable_df.head(10)
Первые 10 строк объекта Frame из datatable
Цвета заголовков указывают на тип данных. Красным цветом обозначены строки, зелёным — целые числа, синим — числа с плавающей точкой.
Вычисление суммарной статистики в pandas
— это операция, для выполнения которой требуется много памяти. В случае с datatable
это не так. Вот команды, которые можно использовать для вычисления различных показателей в datatable
:
datatable_df.sum() datatable_df.nunique()
datatable_df.sd() datatable_df.max()
datatable_df.mode() datatable_df.min()
datatable_df.nmodal() datatable_df.mean()
Вычислим среднее значение по столбцам с использованием datatable
и pandas
и проанализируем время, необходимое для выполнения этой операции.
%%time
datatable_df.mean()
_______________________________________________________________
CPU times: user 5.11 s, sys: 51.8 ms, total: 5.16 s
Wall time: 1.43 s
pandas_df.mean()
__________________________________________________________________
Throws memory error.
Как видно, в pandas
нам не удалось получить результат — выдана ошибка, связанная с памятью.
Frame
и DataFrame
— это структуры данных, представляющие собой таблицы. В datatable
для выполнения манипуляций с данными используются квадратные скобки. Это напоминает то, как работают с обычными матрицами, но здесь при применении квадратных скобок можно пользоваться дополнительными возможностями.
Работа с данными в datatable с использованием квадратных скобок
В математике при работе с матрицами также используются конструкции вида DT[i, j]
. Похожие структуры можно найти в языках C, C++ и R, в пакетах pandas
и numpy
, а так же во многих других технологиях. Рассмотрим выполнение распространённых манипуляций с данными в datatable
.
Следующий код выбирает все строки из столбца funded_amnt
:
datatable_df[:,'funded_amnt']
Выбор всех строк столбца funded_amnt
Вот как выбрать первые 5 строк и 3 столбца:
datatable_df[:5,:3]
Выбор первых 5 строк и 3 столбцов
Отсортируем набор данных по выбранному столбцу:
%%time
datatable_df.sort('funded_amnt_inv')
_________________________________________________________________
CPU times: user 534 ms, sys: 67.9 ms, total: 602 ms
Wall time: 179 ms
%%time
pandas_df.sort_values(by = 'funded_amnt_inv')
___________________________________________________________________
CPU times: user 8.76 s, sys: 2.87 s, total: 11.6 s
Wall time: 12.4 s
Обратите внимание на значительное различие во времени, необходимом на сортировку datatable
и pandas
.
Вот как удалить столбец с именем member_id
:
del datatable_df[:, 'member_id']
Datatable, как и pandas
, поддерживает возможности по группировке данных. Посмотрим на то, как получить среднее по столбцу funded_amound
, данные в котором сгруппированы по столбцу grade
.
%%time
for i in range(100):
datatable_df[:, dt.sum(dt.f.funded_amnt), dt.by(dt.f.grade)]
____________________________________________________________________
CPU times: user 6.41 s, sys: 1.34 s, total: 7.76 s
Wall time: 2.42 s
Здесь вы можете видеть использование конструкции .f
. Это — так называемый фрейм-прокси — простой механизм, позволяющий ссылаться на объект Frame
, с которым в данный момент производятся какие-то действия. В нашем случае dt.f
— это то же самое, что datatable_df
.
%%time
for i in range(100):
pandas_df.groupby("grade")["funded_amnt"].sum()
____________________________________________________________________
CPU times: user 12.9 s, sys: 859 ms, total: 13.7 s
Wall time: 13.9 s
Синтаксис фильтрации похож на синтаксис группировки. Отфильтруем те строки loan_amnt
, для которых значение loan_amnt
больше, чем funded_amnt
.
datatable_df[dt.f.loan_amnt>dt.f.funded_amnt,"loan_amnt"]
Содержимое объекта Frame
можно записать в CSV-файл, что позволяет использовать данные в будущем. Делается это так:
datatable_df.to_csv('output.csv')
О других методах datatable
, предназначенных для работы с данными, можно почитать здесь [14].
Python-модуль datatable
, определённо, работает быстрее привычного многим pandas
. Он, кроме того, прямо-таки находка для тех, кому нужно обрабатывать очень большие наборы данных. Пока единственный минус datatable
в сравнении с pandas
— это объём функционала. Однако сейчас ведётся активная работа над datatable
, поэтому вполне возможно то, что в будущем datatable
превзойдёт pandas
по всем направлениям.
Уважаемые читатели! Планируете ли вы использовать пакет datatable
в своих проектах?
Автор: ru_vds
Источник [15]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/razrabotka/320850
Ссылки в тексте:
[1] Data.table: https://cran.r-project.org/web/packages/data.table/data.table.pdf
[2] data.frame: https://www.rdocumentation.org/packages/base/versions/3.6.0/topics/data.frame
[3] источник: https://github.com/Rdatatable/data.table/wiki
[4] datatable: https://datatable.readthedocs.io/en/latest/?badge=latest
[5] data.table: https://github.com/Rdatatable/data.table
[6] H2O.ai: https://www.h2o.ai/
[7] Driverless.ai: https://www.h2o.ai/driverless-ai/
[8] pandas: https://github.com/pandas-dev/pandas
[9] здесь: https://datatable.readthedocs.io/en/latest/install.html
[10] этом: https://github.com/parulnith/An-Overview-of-Python-s-Datatable-package
[11] здесь: https://mybinder.org/v2/gh/parulnith/An-Overview-of-Python-s-Datatable-package/master?filepath=An%20Overview%20of%20Python%27s%20Datatable%20package.ipynb
[12] Lending Club Loan Data Dataset: https://www.kaggle.com/wendykan/lending-club-loan-data#loan.csv
[13] RFC4180: https://tools.ietf.org/html/rfc4180
[14] здесь: https://datatable.readthedocs.io/en/latest/using-datatable.html
[15] Источник: https://habr.com/ru/post/455507/?utm_campaign=455507&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.