- 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
Источник [17]
Сайт-источник 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] Image: https://ruvds.com/ru-rub/#order
[16] Image: https://ruvds.com/ru-rub/news/read/104
[17] Источник: https://habr.com/ru/post/455507/?utm_campaign=455507&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.