Когда много работаешь с данными, нужно часто строить графики и делать разными преобразования над таблицами. Важно научиться делать это быстро и минимально напрягая мозг. Дело в том, что анализ данных во многом заключается в придумывании и проверке гипотез. Придумывать, конечно, интереснее, чем проверять. Но делать нужно и то и другое. Хорошие инструменты в тренированных руках помогают тратить на техническую работу минимальное количество времени и интеллектуальной энергии.
Я попробовал много инструментов: Excel, Python+Matplotlib, R+ggplot, Python+ggplot, и остановился на связке Python+Pandas+Seaborn. Решил с их использованием уже много задач и хотел бы поделиться наблюдениями.
Я покажу процесс исследования одного странного датасета. Речь пойдёт о расписании всех спортивных мероприятий с участием российских спортсменов за последние 8 лет. Кстати, если у кого-то после прочтения появятся идеи, что с этими данными делать, пожалуйста, напишите, потому что я ничего толкового так и не придумал.
Захватывающий этап парсинга rst и doc-файликов с сайта Минспорта я пропускаю. Предположим, что все данные уже есть в виде DataFrame’a:
data.head()
Таблица не большая, но и не маленькая:
len(data)
76601
Первым делом хотелось бы посмотреть, какие виды спорта представлены:
table = data.groupby('section').size() table
section R4 11 Авиамодельный спорт 1206 Автомобильный спорт 2787 Автомодельный спорт 160 Айкидо 26 Айсшток 49 Академическая гребля 358 Акробатический рок-н-ролл 293 Альпинизм 355 Американский футбол 86 Армейский рукопашный бой 15 Армспорт 159 Бадминтон 698 Баскетбол 1160 Бейсбол 176 Биатлон 1101 Бильярдный спорт 442 Бобслей 53 Бобслей (скелетон) 368 Бодибилдинг 94 Бокс 1374 Борьба на поясах 144 Боулинг 134 ...
Отсортируем:
table = data.groupby('section').size() table = table.sort(inplace=False, ascending=False) table
section Автомобильный спорт 2787 Спорт лиц с поражением ОДА 2469 Фехтование 2253 Мотоциклетный спорт 2025 Дзюдо 2022 Теннис 1770 Велоспорт-шоссе 1561 Легкая атлетика 1511 Футбол 1432 Парусный спорт 1418 Бокс 1374 Конный спорт 1297 Спорт глухих 1277 Волейбол 1208 Авиамодельный спорт 1206 Художественная гимнастика 1196 ...
Достаточно странный топ. Отсортируем не по числу мероприятий, а по числу участников:
table = data.groupby('section').participants.sum() table = table.sort(inplace=False, ascending=False) table
Футбол 535305 Баскетбол 460100 Автомобильный спорт 401397 Танцевальный спорт 307731 Дзюдо 297023 Самбо 219013 Легкая атлетика 217761 Тхэквондо 202859 Киокусинкай 191995 Велоспорт-шоссе 190293 Комплексные мероприятия 187294 Спортивная борьба 177312 Мотоциклетный спорт 176387 Спортивный туризм 153417 Бокс 148654 Хоккей 136849 Кикбоксинг 136099 ...
Так лучше. Теперь нарисуем график для топ-30:
table = data.groupby('section').participants.sum() table = table.sort(inplace=False, ascending=False) table.head(30).plot(kind='bar')
Я не фанат супер-сурового инженерного дизайна, поэтому всегда импортирую Seaborn:
import seaborn table = data.groupby('section').participants.sum() table = table.sort(inplace=False, ascending=False) table.head(30).plot(kind='bar')
Идеально! Никакой другой функциональности Seaborn здесь использовано не будет. У меня чаще всего так и получается — Seaborn появляется только, чтобы графики стали красивыми. Это уже немало, но, вообще, библиотека умеет много чего другого.
Теперь интересно посмотреть на изменение числа мероприятий во времени. Всё то же самое только группировать нужно по дате:
table = data.groupby('start').size() table.plot()
Почти готово. Нужно сделать детализацию, например, по неделям, а не по дням:
table = data.groupby('start').size() table = table.resample('M', how='sum') table.plot()
- Спортивная жизнь зимой наименее активна.
- Тренд до последнего времени восходящий.
- В 2010 был какой-то провал.
Было бы интереснее посмотреть на этот граф в разбивке по видам спорта. Для этого нужно сгруппировать данные по дате и виду спорта:
table = data.pivot_table(index='start', columns='section', values='participants', aggfunc=len) table.head()
И нарисовать:
table.plot()
Блестяще, ничего не понятно. Для начала уберём всё кроме топ-40 видов спорта, кстати, код для расчёта топа уже есть, заново не надо писать:
table = data.groupby('section').size() table = table.sort(inplace=False, ascending=False) order = table.head(40).index table = data.pivot_table(index='start', columns='section', values='participants', aggfunc=len) table = table.reindex(columns=order) table.plot()
Ладно, сделаем детализацию по неделям:
table = data.groupby('section').size() table = table.sort(inplace=False, ascending=False) order = table.head(40).index table = data.pivot_table(index='start', columns='section', values='participants', aggfunc=len) table = table.reindex(columns=order) table = table.resample('M', how='sum') table.plot()
Почти то, что надо, теперь расположим каждую линию на отдельном графике:
table = data.groupby('section').size() table = table.sort(inplace=False, ascending=False) order = table.head(40).index table = data.pivot_table(index='start', columns='section', values='participants', aggfunc=len) table = table.reindex(columns=order) table = table.resample('M', how='sum') table.plot(subplots=True, layout=(8, 5), figsize=(20, 20))
- Для некоторых видов наблюдаются тренды в числе мероприятий:
- Сильно растёт спорт для инвалидов (лиц с поражением ОДА) и автомобильный спорт.
- Слегка растёт мотоциклетный спорт, дзюдо, самбо, парусный спорт, волейбол, тхэквондо, бадминтон.
- У футбола какой-интересный тренд.
- Бокс перестал расти в 2012 году.
- Надо отметить что падения числа мероприятий нигде не наблюдается.
- Иногда есть периодичность в числе мероприятий, что не удивительно:
- Парусный спорт, конные спорт, авиамодельный спорт, велоспорт замирают зимой.
- Вообще зимой у многих видов затишье. Но бывает и наоборот, например, во фристайле.
- Интересный рисунок у тенниса и лёгкой атлетики, который повторяется каждый год
Что мне нравится в этом подходе? Функция plot очень простая, у неё всего несколько важных аргументов: kind, subplots, figsize. Результат зависит в основном от структуры данных, для которых вызывается plot. То есть не нужно осваивать отдельно инструмент для рисования графиков. Нужно научиться преобразовывать данные. С Pandas это сделать не очень сложно. Достаточно выучить несколько «кирпичиков»: groupby, sort, head, pivot_table, reindex, resample, и применять их в разных комбинациях.
ссылка на оригинал статьи http://habrahabr.ru/post/266289/
Добавить комментарий