
Данные, с которыми вы работаете, уже настолько большие, что вы часами ждёте их загрузки? Пора осваивать новый инструмент, который избавит вас от долгого ожидания —datatable!
“В период до 2003 года в мире было создано пять эксабайтов информации. Сейчас же каждые два дня появляются новые пять эксабайтов”, — Эрик Шмидт
Если вы пользовались языком R, то, скорее всего, вы уже работали с пакетом data.table. В R это расширение пакета data.frame. Для пользователей R он полезен в обработке больших объёмов данных (например, около 100 ГБ в RAM).
data.table в R — многофункциональный пакет с высокой производительностью. Он лёгок в использовании, удобен и быстр. Конечно, он очень известен: у него более 400 тысяч скачиваний каждый месяц и его используют почти 650 пакетов CRAN и Bioconductor.
А что делать тем, кто использует Python? Хорошие новости: для этого языка существует библиотека datatable, которая поддерживает большие данные, датасеты как внутри динамической памяти, так и вне, мультипотоковые алгоритмы и обеспечивает высокую производительность.
datatable
Современные программы с использованием машинного обучения должны уметь обрабатывать огромное количество данных и создавать несколько признаков. Это нужно для создания моделей с высокой точностью. Модуль datatable был создан как раз для этого. Он поддерживает данные размером до 100 ГБ на одном вычислительном узле на максимальной скорости вычислений. Разработка библиотеки спонсировалась H2O.ai и впервые использовалась в Driverless.ai.
В некоторой степени библиотека похожа на pandas с тем лишь отличием, что она больше сфокусирована на данных больших размеров и скорости вычислений. К тому же datatable помогает пользователю понятными сообщениями об ошибках. Сейчас вы и сами увидите, в чём эта библиотека превосходит pandas.
Установка
На MacOS установка производится при помощи pip:
pip install datatable
На Linux — при помощи бинарного пакета:
# Если у вас Python 3.5 pip install http://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 http://s3.amazonaws.com/h2o-release/datatable/stable/datatable-0.8.0/datatable-0.8.0-cp36-cp36m-linux_x86_64.whl
К сожалению, пока библиотека не работает на Windows, но ведётся работа для создания поддержки и этой ОС.
Для более подробной инструкции обращайтесь к документации.
Код, использованный в этой статье, можно найти на Github.
Считывание данных
Датасет — Lending Club Loan Data — взят с Kaggle. Он содержит информацию обо всех займах в период с 2007 по 2015 год: статус займа (текущий, выплачен в срок, выплачен позже срока) и информацию об оплате. Файл состоит из 2,26 миллионов строк и 145 столбцов. Размер датасета идеален для демонстрации возможностей библиотеки.
# Импортируем библиотеки import numpy as np import pandas as pd import datatable as dt
Загрузим данные в объект Frame. Это фундаментальная единица анализа в библиотеке datatable — почти то же самое, что и pandas dataframe или таблица SQL: данные содержатся в форме двумерного массива.
datatable
%%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.
К тому же парсер datatable:
- автоматически распознаёт сепараторы, заголовки, типы столбцов и тому подобное;
- может считывать данные из многих ресурсов: файлов, ссылок, текстов, архивов, программных оболочек и масок;
- позволяет проводить многопоточное чтение файла;
- показывает полосу загрузки больших файлов;
- считывает как RFC4180-совместимые, так и несовместимые файлы.
pandas
Теперь посмотрим на то, как с задачей загрузки справляется 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 работает гораздо быстрее: считывание заняло меньше минуты.
Преобразование объекта Frame
Существующий объект Frame можно преобразовать в массив numpy или pandas dataframe:
numpy_df = datatable_df.to_numpy() pandas_df = datatable_df.to_pandas()
Давайте преобразуем наши данные в объект pandas 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
Получается, что для работы с объектом pandas dataframe гораздо эффективнее считать данные при помощи datatable, а затем преобразовать их в pandas dataframe.
type(datatable_pandas) ___________________________________________________________________ pandas.core.frame.DataFrame
Свойства Frame
Давайте рассмотрим основные свойства этого класса. Кстати, они схожи со свойствами pandas dataframe.
print(datatable_df.shape) # (строки, столбцы) print(datatable_df.names[:5]) # названия первых пяти столбцов print(datatable_df.stypes[:5]) # типы первых пяти столбцов ______________________________________________________________ (2260668, 145) ('id', 'member_id', 'loan_amnt', 'funded_amnt', 'funded_amnt_inv') (stype.bool8, stype.bool8, stype.int32, stype.int32, stype.float64)
Также можно использовать команду head для того, чтобы вывести несколько первых строк датасета:
datatable_df.head(10)

Первые 10 строк датасета
Цвет показывает тип данных: красный — строки, зелёный — целые числа, синий — числа с плавающей точкой.
Сводная статистика
В pandas подсчёт сводной статистики — достаточно ресурсозатратный процесс. С 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
%%time datatable_df.mean() _______________________________________________________________ CPU times: user 5.11 s, sys: 51.8 ms, total: 5.16 s Wall time: 1.43 s
pandas
pandas_df.mean() __________________________________________________________________ Throws memory error.
Как видим, для такого размера данных с pandas это сделать невозможно, так как происходит ошибка памяти.
Обработка данных
datatable — столбчатая структура данных, как и dataframe. Все обращения происходят при помощи квадратных скобок, как и в обычных матрицах, но с большим функционалом.
Такая же нотация DT[i, j] используется в математике при работе с матрицами, в C/C++, R, pandasи numpy. Давайте посмотрим, что мы можем делать с данными в datatable.
Выбор подмножества строк/столбцов
Нижеприведённый код выбирает весь столбец funded_amnt датасета.
datatable_df[:,'funded_amnt']
А вот так мы можем выбрать первые пять строк и три столбца:
datatable_df[:5,:3]
![datatable_df[:5,:3] datatable_df](http://cdn-images-1.medium.com/max/800/1*_V71gWvQEhaRelnDe1_pRg.png)
Сортировка датасета
Отсортируем его по значению funded_amnt_inv при помощи обеих библиотек и сравним время работы.
datatable
%%time datatable_df.sort('funded_amnt_inv') _________________________________________________________________ CPU times: user 534 ms, sys: 67.9 ms, total: 602 ms Wall time: 179 ms
pandas
%%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.
Удаление строк/столбцов
Вот так можно удалить столбец с названием member_id:
del datatable_df[:, 'member_id']
Группирование
Как и pandas, datatable поддерживает функцию groupby. Давайте найдём среднее значение столбца funded_amount, сгруппированного по значению grade.
datatable
%%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
pandas
%%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
Что такое .f?
f это frame proxy, который позволяет нам обращаться к объекту Frame. То есть в нашем примере dt.f — это то же самое, что и datatable_df.
Фильтрация строк
Синтаксис похож на groupby. Давайте выберем только те строки 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 определённо ускоряет работу с данными по сравнению с pandas, что очень полезно при работе с большими датасетами. С другой стороны, библиотека проигрывает pandas в функциональности. Но работа над библиотекой до сих пор ведётся, поэтому в будущем надеемся на расширение функционала.
Специально для сайта ITWORLD.UZ. Новость взята с сайта NOP::Nuances of programming