Данные, с которыми вы работаете, уже настолько большие, что вы часами ждёте их загрузки? Пора осваивать новый инструмент, который избавит вас от долгого ожидания —datatable!
Если вы пользовались языком 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]
Сортировка датасета
Отсортируем его по значению 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