Бигдата и такси: как найти самое нагруженное время
hard

Бигдата и такси: как найти самое нагруженное время

Анализируем миллион записей и смотрим на результат

Сегодня будет простой проект с бигдатой на Python: мы проанализируем миллион записей и посмотрим, в какой день недели и время совершается больше всего поездок.

Если коротко, то бигдата — это какой-то большой набор данных: сотни тысяч и миллионы записей. Их можно специальным образом обработать и получить понятный анализ по разным направлениям: чего получилось больше, чего меньше, что с чем связано и как одно зависит от другого. Например, после анализа бигдаты с твитами Байдена и Трампа стало понятно, что за одного твиты пишет команда, а второй постит сам, от чистого сердца.

Что делаем

Мы нашли большой датасет (1 028 136 записей) с записями вызовов такси Uber в США, где хранятся:

  • дата и время вызова;
  • координаты, откуда клиент вызвал такси;
  • порядковый номер местной станции Uber.

Попробуем проанализировать эти данные и понять, в какое время там вызывают такси чаще всего и правда ли, что в выходные такси пользуются чаще, чем в будни. Для этого мы напишем программу на Python и добавим визуализацию — построим понятные графики с распределением вызовов.

Считываем и проверяем датасет

Создадим новый Python-файл в той же папке, где лежит датасет, и импортируем сразу две библиотеки: одну для работы с данными, а вторую — для визуализации:

# добавляем библиотеку для анализа датасета
import pandas as pd

# и библиотеку для визуализации
import matplotlib.pyplot as plt

Считаем файл с записями и сразу убедимся, что данные подгрузились правильно. Для этого выведем первые и последние 5 записей. Первые нам нужны для проверки, а последние — чтобы убедиться, что в датасете нет в конце мусорных или лишних служебных данных:

# считываем файл с записями
uber_df= pd.read_csv("uber-raw-data-sep14.csv")

# выводим первые 5 записей, чтобы убедиться, что файл считался правильно
print(uber_df.head(5))

# смотрим на последние 5 записей 
print(uber_df.tail())
Бигдата и такси: как найти самое нагруженное время

После запуска кода в консоли появляются два списка — начало и конец датасета. Видно, что данные хранятся в одном и том же формате и под конец датасета не происходит ничего критичного — всё то же самое, что и в начале. Это значит, что с таким набором данных можно двигаться дальше.

Ещё мы узнали, как называется каждый столбец, — это нам пригодится на следующем этапе, когда мы будем переделывать весь датасет.

Подготавливаем данные

Чтобы программа смогла проанализировать данные и построить графики, нам нужно привести дату и время в стандартный вид: преобразовать её в формат datetime, из которого легко извлекать часы, минуты и дни.

Чтобы это сделать, используем команду .to_datetime():

# переводим дату и время из строки в стандартный формат для даты
uber_df['Date/Time']= pd.to_datetime(uber_df['Date/Time'])

Теперь мы можем использовать все преимущества нового формата и выделить оттуда отдельно в новые колонки:

  • день,
  • час,
  • день недели.

Эти данные мы будем использовать для анализа и визуализации.

# получаем день заказа из стандартной даты и кладём его в новую колонку
uber_df["Day"] = uber_df["Date/Time"].apply(lambda x: x.day)
# точно так же получаем час
uber_df["Hour"] = uber_df["Date/Time"].apply(lambda x: x.hour)
# и номер дня недели
uber_df["Weekday"] = uber_df["Date/Time"].apply(lambda x: x.weekday())
# выводим первые 5 записей в новой таблице
print(uber_df.head(5))
Бигдата и такси: как найти самое нагруженное время

Таблица явно изменилась: в конце появились три новые колонки с номером дня, часа и порядковым номером дня недели. Если интересно, почему день недели начинается с нуля, — почитайте нашу статью про нумерацию в компьютере.

Визуализируем данные

У нас всё готово для того, чтобы представить эти данные в понятной форме — например в виде картинок и графиков.

Начнём с распределения по дням недели — построим график и посмотрим, в какие числа вызывают такси чаще всего. Чтобы это сделать, нам нужно:

  1. Подготовить холст — виртуальный макет, где будет располагаться картинка.
  2. Нарисовать гистограмму — специальный график, который состоит из небольших столбиков. Чем выше столбик — тем больше вызовов.
  3. Подписать оси — так будет понятно, что происходит на картинке.
  4. Сохранить изображение в файл.

Сделаем это всё сразу и подпишем комментариями каждый фрагмент кода:

# Делаем визуализацию распределения вызовов в зависимости от дня в месяце
# готовим холст
fig,ax = plt.subplots(figsize = (12,6))
# строим гистограмму распределения по дням
plt.hist(uber_df.Day, width= 0.6, bins= 30)
# подписываем оси
plt.title("Распределение вызовов в течение месяца", fontsize=16)
plt.xlabel("День", fontsize=14)
plt.ylabel("Плотность вызовов", fontsize=14)
# сохраняем картинку
plt.savefig('day.png', dpi=120)
Бигдата и такси: как найти самое нагруженное время

На графике явно видна какая-то динамика — есть повторяющиеся спады и подъёмы спроса на такси. Причём если посчитать дни недели (а первое число в датасете — это понедельник), то увидим, что спрос растёт к концу недели, а потом резко падает. Можно сделать первоначальный вывод, что с пятницы по воскресенье у нас будет повышенный спрос, а значит, хорошо бы, чтобы в это время в городе было больше водителей, чем в понедельник.

Чтобы это проверить, посмотрим на распределение количества вызовов по дням недели, где 0 это понедельник, а 6 — воскресенье:

# Делаем визуализацию распределения вызовов в зависимости от дня недели
# готовим холст
fig,ax = plt.subplots(figsize = (12,6))
# строим гистограмму распределения по дням недели
plt.hist(uber_df.Weekday, width= 0.6, range= (0, 6.5), bins=7, color= "green")
# подписываем оси
plt.title("Распределение вызовов по дням недели", fontsize=16)
plt.xlabel("День недели", fontsize=14)
plt.ylabel("Плотность вызовов", fontsize=14)
# сохраняем картинку
plt.savefig('weekday.png', dpi=120)
Бигдата и такси: как найти самое нагруженное время

А вот тут картина уже другая: мы видим рост спроса к выходным, но в воскресенье он внезапно становится ниже. Получается, что нам нужно скорректировать предыдущий вывод и планировать высокую нагрузку только на пятницу и субботу.

Ещё заметен внезапный всплеск спроса во вторник. С чем он связан — это уже должны думать аналитики. 

Напоследок посмотрим на распределение вызовов по часам:

# Делаем визуализацию распределения вызовов в течение суток
# готовим холст
fig,ax = plt.subplots(figsize = (12,6))
# строим гистограмму распределения по часам
plt.hist(uber_df.Hour, width= 0.6, bins=24, color= "orange")
# подписываем оси
plt.title("Распределение вызовов по часам", fontsize=16)
plt.xlabel("Часы", fontsize=14)
plt.ylabel("Плотность вызовов", fontsize=14)
# сохраняем картинку
plt.savefig('hours.png', dpi=120)
Бигдата и такси: как найти самое нагруженное время

Тут очевидный всплеск с утра, когда все хотят попасть на работу, а с 15:00 начинается вторая волна — деловые поездки, которые плавно переходят в режим «добраться до дома». Это значит, что водителю проще всего получить заказ с 15 до 21 часа.

Что можно сделать ещё

Вот какие данные можно ещё достать из этого датасета:

  • в какой день недели какие часы самые свободные, а какие — загруженные;
  • в какой район больше всего вызовов и когда;
  • на каком участке больше всего вызовов;
  • есть ли зависимость между номером участка и количеством вызовов в разное время;
  • самое удачное время для водителя (когда больше всего заказов);
  • самое удачное время для клиентов (когда больше вероятность быстро вызвать свободную машину).

И всё это делается несколькими выражениями в Python, применёнными к библиотеке для визуализации данных. 

Вот так дата-сайентисты и работают. И за это платят.

# добавляем библиотеку для анализа датасета
import pandas as pd 

# и библиотеку для визуализации
import matplotlib.pyplot as plt

# считываем файл с записями
uber_df= pd.read_csv("uber-raw-data-sep14.csv")

# выводим первые 5 записей, чтобы убедиться, что файл считался правильно
print(uber_df.head(5))

# смотрим на последние 5 записей 
print(uber_df.tail())

# переводим дату и время из строки в стандартный формат для даты
uber_df['Date/Time']= pd.to_datetime(uber_df['Date/Time'])

# получаем день заказа из стандартной даты и кладём его в новую колонку
uber_df["Day"] = uber_df["Date/Time"].apply(lambda x: x.day)
# точно так же получаем час
uber_df["Hour"] = uber_df["Date/Time"].apply(lambda x: x.hour)
# и номер дня недели
uber_df["Weekday"] = uber_df["Date/Time"].apply(lambda x: x.weekday())
# выводим первые 5 записей в новой таблице
print(uber_df.head(5))

# Делаем визуализацию распределения вызовов в зависимости от дня в месяце
# готовим холст
fig,ax = plt.subplots(figsize = (12,6))
# строим гистограмму распределения по дням
plt.hist(uber_df.Day, width= 0.6, bins= 30)
# подписываем оси
plt.title("Распределение вызовов в течение месяца", fontsize=16)
plt.xlabel("День", fontsize=14)
plt.ylabel("Плотность вызовов", fontsize=14)
# сохраняем картинку
plt.savefig('day.png', dpi=120)

# Делаем визуализацию распределения вызовов в зависимости от дня недели
# готовим холст
fig,ax = plt.subplots(figsize = (12,6))
# строим гистограмму распределения по дням недели
plt.hist(uber_df.Weekday, width= 0.6, range= (0, 6.5), bins=7, color= "green")
# подписываем оси
plt.title("Распределение вызовов по дням недели", fontsize=16)
plt.xlabel("День недели", fontsize=14)
plt.ylabel("Плотность вызовов", fontsize=14)
# сохраняем картинку
plt.savefig('weekday.png', dpi=120)


# Делаем визуализацию распределения вызовов в течение суток
# готовим холст
fig,ax = plt.subplots(figsize = (12,6))
# строим гистограмму распределения по часам
plt.hist(uber_df.Hour, width= 0.6, bins=24, color= "orange")
# подписываем оси
plt.title("Распределение вызовов по часам", fontsize=16)
plt.xlabel("Часы", fontsize=14)
plt.ylabel("Плотность вызовов", fontsize=14)
# сохраняем картинку
plt.savefig('hours.png', dpi=120)

Рекламная интеграция

Чтобы научиться делать правильные выводы из бигдаты, приходите в Практикум на курсы «Аналитик данных». Если надо побыстрее — приходите на буткемп: объём примерно тот же, но занятия вдвое интенсивнее.

Обложка:

Даня Берковский

Корректор:

Ирина Михеева

Вёрстка:

Кирилл Климентьев

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Вам может быть интересно
hard