Как стать автором
Обновить
2700.13
RUVDS.com
VDS/VPS-хостинг. Скидка 15% по коду HABR15

Как обработать датафрейм с миллиардами записей за считанные секунды?

Время на прочтение4 мин
Количество просмотров16K
Автор оригинала: Roman Orac
Анализ больших данных в Python переживает эпоху возрождения. Она началась с библиотеки NumPy. Эта библиотека, кстати, является одной из составных частей тех инструментов, о которых пойдёт речь в этом материале. В 2006 году тема обработки больших данных постепенно набирала обороты, этот процесс ускорился с появлением Hadoop. Потом появилась библиотека pandas со своими структурами данных DataFrame, которые обычно называют просто «датафреймами». В 2014 году большие данные стали мейнстримом, в этом же году появилась платформа Apache Spark. В 2018 году вышла библиотека Dask и другие средства для анализа данных в Python.



Каждый месяц мне попадаются новые инструменты для анализа данных в Python, которые мне очень хочется освоить. Потратив час-другой на их изучение, можно, в долгосрочной перспективе, сэкономить немало времени. Кроме того, важно следить за тем новым, что происходит в интересующей тебя сфере технологий. Возможно, вы полагаете, что эта статья будет посвящена библиотеке Dask. Но это не так. Сегодня я расскажу вам об одной недавно обнаруженной мной Python-библиотеке, о которой стоит знать тем, кто занимается анализом данных.

Python-библиотека Vaex



Vaex — это высокопроизводительная Python-библиотека, предназначенная для организации «ленивой» обработки датафреймов (похожих на датафреймы pandas), рассчитанная на визуализацию и исследование больших наборов табличных данных. Эта библиотека умеет вычислять основные статистические показатели по исследуемым данным. При этом обработка миллиарда записей может составлять что-то около секунды. Библиотека поддерживает множество средств визуализации, что помогает исследовать большие данные в интерактивном режиме.

Сравнение Vaex и Dask



Библиотека Vaex не похожа на Dask, но используемые в ней структуры данных похожи на сущности DataFrame, применяемые в Dask. Они построены на базе датафреймов pandas. Это означает, что Dask получает в наследство от pandas определённые ограничения по работе с датафреймами. Например — требование, в соответствии с которыми данные, которые планируется обрабатывать, должны быть полностью загружены в память. В случае с Vaex это не так.

Vaex не делает копий датафреймов, в результате средствами этой библиотеки можно обрабатывать масштабные датафреймы на компьютерах с небольшим объёмом оперативной памяти.

И Vaex и Dask используют «ленивые» механизмы обработки данных. Основное различие между ними заключается в том, что Vaex вычисляет значения полей тогда, когда они нужны, а в Dask надо явным образом использовать функцию вычисления значений.

Для того чтобы раскрыть весь потенциал Vaex нужно, чтобы данные были бы представлены в формате HDF5 или Apache Arrow.

Установка Vaex


Установить Vaex так же легко, как и любой другой Python-пакет:

pip install vaex

Эксперименты с Vaex


Создадим датафрейм pandas, в котором содержится 1 миллион строк и 1000 столбцов. Это позволит нам получить большой файл с данными.

import vaex
import pandas as pd
import numpy as np
n_rows = 1000000
n_cols = 1000
df = pd.DataFrame(np.random.randint(0, 100, size=(n_rows, n_cols)), columns=['col%d' % i for i in range(n_cols)])
df.head()

Вот как выглядят эти данные.


Данные для проведения эксперимента

Сколько оперативной памяти использует этот датафрейм?

df.info(memory_usage='deep')



Сведения об использовании памяти

Сохраним этот датафрейм на диск для того чтобы потом прочитать его с помощью Vaex.

file_path = 'big_file.csv'
df.to_csv(file_path, index=False)

Если напрямую прочитать этот CSV-файл с помощью Vaex, особых выгод мы от этого не получим. Скорость чтения будет похожей на скорость, обеспечиваемую pandas. На моём ноутбуке и Vaex и pandas читают эти данные примерно за 85 секунд.

Для того чтобы увидеть возможности Vaex, CSV-данные нужно преобразовать в формат HDF5 (Hierarchical Data Format version 5). В Vaex есть функция для выполнения такого преобразования, которая позволяет работать с данными, объём которых превышает объём доступной оперативной памяти. Это достигается благодаря тому, что исходные данные разбиваются на фрагменты.

Если не удаётся, из-за нехватки памяти, открыть достаточно большой файл с помощью pandas, этот файл можно преобразовать в формат HDF5 и обработать с помощью Vaex.

dv = vaex.from_csv(file_path, convert=True, chunk_size=5_000_000)

Вышеприведённая функция автоматически создаёт HDF5-файл и сохраняет его на диск.

Проверим тип переменной dv:

type(dv)
# вывод
vaex.hdf5.dataset.Hdf5MemoryMapped

Теперь прочитаем набор данных объёмом 7.5 Гб с помощью Vaex. Прямо сейчас нам его читать не придётся — дело в том, что его уже представляет переменная dv. Но следующую команду мы всё же запустим, сделав это для того чтобы узнать о том, какова скорость выполнения этой операции:

dv = vaex.open('big_file.csv.hdf5')

На выполнение этой команды у Vaex уходит меньше секунды. Но Vaex, на самом деле, из-за использования механизмов «ленивой» обработки данных, этот файл не читает.

Теперь давайте заставим Vaex прочитать файл, посчитав сумму значений в столбце col1:

suma = dv.col1.sum()
suma
# array(49486599)

А вот эта команда меня по-настоящему удивила. Для вычисления суммы Vaex тоже понадобилось меньше секунды. Как это возможно? А возможно это благодаря мэппингу памяти.

Визуализация данных


Vaex показывает хорошую скорость и на визуализации данных. В библиотеке есть особые функции: plot1d, plot2d и plot2d_contour.

dv.plot1d(dv.col2, figsize=(14, 7))



Результат визуализации данных

Виртуальные столбцы


Vaex, при добавлении к набору данных нового столбца, создаёт виртуальный столбец. Он не занимает память. Значения, хранящиеся в нём, вычисляются, что называется, «на лету».

dv['col1_plus_col2'] = dv.col1 + dv.col2
dv['col1_plus_col2']



Новый столбец

Эффективная фильтрация данных


Vaex не создаёт копий датафреймов при фильтрации данных. Это способствует более эффективному использованию памяти.

dvv = dv[dv.col1 > 90]

Агрегирование данных


В Vaex агрегирование данных работает немного не так, как в pandas. Но самое важное тут то, что в Vaex эта операция выполняется очень быстро.

Создадим новый столбец, содержащий результаты сравнения dv.col1 >= 50:

dv['col1_50'] = dv.col1 >= 50

Vaex комбинирует операции группировки и агрегирования данных в одной команде. Следующая команда группирует данные по столбцу col1_50 и вычисляет сумму столбца col3:

dv_group = dv.groupby(dv['col1_50'], agg=vaex.agg.sum(dv['col3']))
dv_group



Результаты выполнения команды

Соединения данных


Vaex позволяет соединять данные без создания копий данных в памяти. Это, как и другие возможности библиотеки, способствует экономному использованию памяти. Функция join, показанная ниже, покажется знакомой пользователям pandas:

dv_join = dv.join(dv_group, on=’col1_50')

Итоги


В этом материале мы рассмотрели основные особенности и возможности библиотеки Vaex. Если она вас заинтересовала — загляните в её репозиторий.

А вам пригодится библиотека Vaex?



Теги:
Хабы:
Всего голосов 43: ↑40 и ↓3+37
Комментарии9

Публикации

Информация

Сайт
ruvds.com
Дата регистрации
Дата основания
Численность
11–30 человек
Местоположение
Россия
Представитель
ruvds