Следующая тема: ИАД. Проектная работа

Вернуться в раздел: Исследовательский анализ данных

Вернуться в оглавление: Я.Практикум

Введение

Вы сделали всё, чтобы получить список тех сетей АЗС, с которыми Яндекс.Навигатору выгоднее начать сотрудничество.

Чему вы научитесь

  • строить столбчатые графики и круговые диаграммы;
  • выборочно изменять значения в списке методом where();
  • писать цикл, который строит сразу много гистограмм.

Вам предстоит:

  • объединить мелкие сети в группу «Другие»;
  • построить гистограммы продолжительности заправки в каждой сети;
  • получить финальный список крупных сетей АЗС.

Сколько времени это займёт

2 урока по 30 минут.

Постановка задачи

Перепроверьте реалистичность данных, чтобы подготовить финальный отчёт для руководства.

Укрупняем группы

Перед тем как делать выводы, надо перепроверить реалистичность данных. Отчёт выглядит так. Напомним, что достоверная типичная продолжительность заправки указана в median_time:

print(final_stat)

                         time_spent  good_time_spent  median_time  stations
name                                                           
Агератум     337.802721            309.0       308.50       3.0
Амарант      132.760012            187.5       169.00       5.0
Аммобиум     256.708042            180.5       178.75       4.0
Арктотис      73.879984            185.0       190.50       3.0
Астильба     376.143149            423.0       435.50       4.0
Бальзамин    134.508411            158.0       158.00       1.0
Бархатцы     145.300328            181.5       181.50       1.0
Бегония      163.200647            195.0       190.00       3.0

Фасоль       133.631957              NaN          NaN       NaN
Функия       302.494737            171.5       171.50       1.0
Хризантема   195.738710            188.0       188.25       2.0

0 молоко
1 хамон
2 хлеб
3 картошка
4 огурцы
dtype: object

0 молоко
1 обойдусь
2 хлеб
3 картошка
4 огурцы
dtype: object

dataframe.dropna(subset=['column_name'])

Результат

             time_spent  good_time_spent  median_time  stations
name
Василёк      268.849897            264.0       252.00     103.0
Гейхера      167.445947            204.0       192.00      12.0
Календула    207.357323            254.0       240.00      36.0
Колокольчик  119.131564            161.0       161.00      21.0
Люпин        235.440937            186.0       200.00      13.0
Мальва       136.562234            182.0       177.75      22.0
Немезия      186.535207            226.0       227.50      21.0
Роза         260.877217            315.0       350.00      18.0

Вы получили «большую восьмёрку». Это лучше, чем «двадцатка» — договориться проще.

import pandas as pd

data = pd.read_csv('/datasets/visits.csv', sep='\t')

# фильтруем слишком быстрые и медленные заезды и АЗС
data['too_fast'] = data['time_spent'] < 60
data['too_slow'] = data['time_spent'] > 1000
too_fast_stat = data.pivot_table(index='id', values='too_fast')
good_ids = too_fast_stat.query('too_fast < 0.5')
good_data = data.query('id in @good_ids.index')
good_data = good_data.query('60 <= time_spent <= 1000')

# считаем данные по отдельным АЗС и по сетям
station_stat = data.pivot_table(index='id', values='time_spent', aggfunc='median')
good_stations_stat = good_data.pivot_table(index='id', values='time_spent', aggfunc='median')
stat = data.pivot_table(index='name', values='time_spent')
good_stat = good_data.pivot_table(index='name', values='time_spent', aggfunc='median')
stat['good_time_spent'] = good_stat['time_spent']

id_name = good_data.pivot_table(index='id', values='name', aggfunc=['first', 'count'])
id_name.columns = ['name', 'count']
station_stat_full = id_name.join(good_stations_stat)

# считаем показатели сетей из показателей АЗС,
# а не усреднённые заезды на все АЗС сети
good_stat2 = (
    station_stat_full
    .query('count > 30')
    .pivot_table(index='name', values='time_spent', aggfunc=['median', 'count'])
)
good_stat2.columns = ['median_time', 'stations']
final_stat = stat.join(good_stat2)

big_nets_stat = final_stat.query('stations > 10')
station_stat_full['group_name'] = station_stat_full['name'].where(station_stat_full['name'].isin(big_nets_stat.index), 'Другие')
print(station_stat_full.head())

Результат

                 name  count  time_spent   group_name
id
00ca1b70     Вероника    131       166.0       Другие
0178ce70      Василёк    164       234.5      Василёк
01abf4e9      Гацания     30       181.5       Другие
030a9067  Колокольчик    228       135.5  Колокольчик
03740f2d      Василёк    157       289.0      Василёк

Да, иногда аналитические выводы похожи на сюжеты бульварных романов: «Василёк остался прежним, а Вероника стала другой». Не обращайте внимания, вы-то всё правильно сделали.

Результат

             time_spent  count
group_name
Колокольчик      161.00     21
Мальва           177.75     22
Гейхера          192.00     12
Люпин            200.00     13
Другие           208.75    104
Немезия          227.50     21
Календула        240.00     36
Василёк          252.00    103
Роза             350.00     18

Медленнее всего обслуживают в «Розе». «Василёк», «Календула» и «Немезия» тоже не могут особо похвастаться. Надо что-то делать с уровнем сервиса. Если долго смотреть на машину с пустым бензобаком, можно увидеть, как она уезжает заправляться к конкурентам!

IT_names = pd.DataFrame(
    {
        'name': ['Саша', 'Саша', 'Саша', 'Игорь', 'Игорь', 'Максим', 'Максим'],
        'surname': [
            'Иванов',
            'Попов',
            'Сидоров',
            'Смирнов',
            'Крылов',
            'Курепов',
            'Максимов',
        ],
    }
)
print(IT_names)
print()
for developer_name, developer_data in IT_names.groupby('name'):
    print(
        'Имя {} встречается {} раза'.format(
            developer_name, len(developer_data)
        )
    )

     name   surname
0    Саша    Иванов
1    Саша     Попов
2    Саша   Сидоров
3   Игорь   Смирнов
4   Игорь    Крылов
5  Максим   Курепов
6  Максим  Максимов

Имя Игорь встречается 2 раза
Имя Максим встречается 2 раза
Имя Саша встречается 3 раза

name    surname
Игорь    2
Максим    2
Саша    3

Результат работы функции, применённой к groupby(), становится аналогом pivot_table(). Однако нас интересует перебор значений в цикле. Постройте гистограммы для каждой из сетей.

Результат

         date_time        id  time_spent  ... too_fast  too_slow  group_name
0  20180406T165358  76144fb2        98.0  ...    False     False     Василёк
2  20180403T172824  76144fb2       220.0  ...    False     False     Василёк
6  20180402T082321  76144fb2       555.0  ...    False     False     Василёк
7  20180407T003408  76144fb2       286.0  ...    False     False     Василёк
9  20180405T131939  76144fb2       248.0  ...    False     False     Василёк

[5 rows x 7 columns]

Вы создали group_name, теперь с ним можно проделывать разное волшебство. Масса возможностей хранить одно в другом:
group_name в group_data, 
group_data в цикле for - in, 
игла в яйце,
яйцо в утке,
утка в зайце,
заяц в шоке.

 

Следующая тема: ИАД. Проектная работа

Вернуться в раздел: Исследовательский анализ данных

Вернуться в оглавление: Я.Практикум