В плане работы с большими данными я всегда была везунчиком - мне никогда не приходилось переживать, что датасет не влезает в память. Мне либо давали уже очищенные и предагрегированные данные адекватного размера или на работе был сервер с мощностью достаточной для хранения и обработки файлов в 20 млн строк.
Но тут случилось PhD, которое поставило передо мной задачу обработки мобильных сигналов, собранных за 4 года. Для понимания объем каждого квартала около 100 млн строк. Тем временем оперативная память университетского сервера оказалась слабее моего компьютера, а NDA не позволяет загружать данные в облачные хранилища.
Пришлось учиться обрабатывать такой объем на компьютере. Оказалось, что не все так страшно- каждый из нас сможет разобраться.
Disclaimer: Я не претендую на роль эксперта, наоборот, я точно новичок в этом вопросе. Пост о том, где смотреть и с чего начать, чтобы было не страшно расскажу.
Идея
Начну с идеи: как возможно обрабатывать файл в 20 ГБ, если оперативная память только 16? Очень просто: нужно разделить файл на части, которые в эту память помещаются, обработать каждый по отдельности или по-нескольку в параллели, и сохранить результат. Разделение на части называется partitioning, партиционирование.
Делить можно разными способами: или фиксируя объем каждого файла или по значению переменной, например по дате или геохешу.
На выходе вместо одного файла у вас получится папка, внутри которой будут находится файлы с частями, соответствующими определенному значению переменной, по которой вы файл партиционировали.
Dask
Для обработки больших данных в Python удобнее всего использовать библиотеку Dask - большинство функций такие же как в pandas, с главным отличием, что команды не выполняются, а значит память не занимается, пока не написать compute().
Так выгляди dask dataframe до того как сохранить его в pandas dataframe ( по сути метаданные):
В примере выше разделение на партиции прошло не заметно для нас- по дефолту dask загружает файл кусочками по 64 MB. При этом можно явно указывать размер:
df = dd.read_csv('big_data.csv', blocksize='64MB')
Партиционирование по месяцам
Чаще всего работа с файлом не заканчивается на 2 фильтрах и паре статистик. Но чтобы заниматься аналитикой, хочется уметь посмотреть на сами данные в разных разрезах.
Например, моей конечной задачей является определение дома и работы для каждого юзера на каждый по месяц. И сделать это не посмотрев на распределения сигналов и "не покрутив данные" невозможно. То есть моя задача - привести данные к размеру подходящему для pandas dataframe.
Поэтому я разбила исходные файлы на месяцы, и потом с каждым месяцем работала отдельно в pandas.
Мои шаги:
- прочитать квартальный файл ( ~14gb) с мобильными сигналами
- применить к нему фильтры
- создать из timestamp сигнала колонку месяц
- сохранить результат с партиционированием по месяцу.
В моем случае я использую append, поскольку записываю несколько непартиционированных parquets в один квартальный партиционированный по месяцу. Если у вас один файл изначально, то append не нужен.
Чтобы считать нужный месяц, нужно просто указать номер в фильтре. Вуаля, теперь есть файл, который легко влезет в pandas dataframe.
Dask_geopandas
В Python есть отдельная библиотека для геоопераций на базе dask - dask_geopandas. Мне практически не пришлось с ней работать, но если ваши фильтры или партиции связаны с пространством, то она вам понадобиться.
Самый очевидный usecase: сам файл влезает в оперативную память его считали в pandas dataframe, но пространственная операция над ним уже либо не влезает, либо занимает много времени.
В этом примере моя функция создает партиционированную колонку с геометрией the_geom и обрезает датасет по границам полигона df.within(boundaries). Попытка сделать такую операцию над 11 млн строк в обычном geopandas закончилась kernel restart:(
И снова, для того, чтобы фильтр выполнился, необходимо написать compute
Пример как делать spatial partitioning
Напишите, если пост помог вам разобраться с обработкой больших данных, и, если есть интерес к таким техническим постам.
А я вам вам напоминаю, что о моем курсе по основам пространственного анализа с использованием Python. Наша цель — показать, как геоаналитические методы могут быть применены в бизнесе.
Курс предназначен для:
- GIS-специалистов с базовыми знаниями Python, которые хотят развить свои аналитические навыки;
- Аналитиков, которым необходимы геоинструменты для решения задач.
Курс полностью самостоятелен и включает возможность обсуждения в нашем чате в Telegram.
Посетите наш сайт, пройдите тест и присоединяйтесь к курсу. А для тех, кто еще сомневается, подходит эта профессия или нет, мы подготовили демо-версию курса за символическую цену, все подробности по ссылке геокурса!