Следующая тема: ИАД. Работа с несколькими источниками данных

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

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

1. Введение

2. Срезы данных и поиск авиабилетов

3. Срезы данных методом query()

4. Возможности queru()

5. Срезы в действии

6. "Слишком долгая" заправка - это сколько?

7. Работа с датой и временем

8. Графики

9. Группировка с pivot_table()

10. Помечаем срез данных

11. Диаграмма размаха в Python

12. Сохраняем результаты

13. Заключение

14. Проверочные задания. Изучение cрезов

Введение

Вы получили общее представление о данных — самое время исследовать их более тщательно.

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

  • Получать срезы данных вручную и методом query().
  • Округлять время и переводить его в другие часовые пояса.
  • Строить графики методом plot().
  • Составлять правильные баг-репорты.

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

  • Изучить АЗС со сверхдолгими заправками;
  • Определить границу, после которой можно считать заправку «слишком долгой»;
  • Узнать, чем ночные заезды отличаются от дневных;
  • Найти аномально быстрые заправки.

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

10 уроков от 5 до 30 минут.

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

Погрузитесь в детали: найдите аномально быстрые и сверхдолгие заправки. Узнайте, для каких АЗС они характерны.

FromToIs_DirectHas_luggagePriceDate_FromDate_ToAirlineTravel_time_fromTravel_time_to
0 Moscow Rome False True 21032 01.07.19 07.07.19 Belavia 995 350
1 Moscow Rome True False 19250 01.07.19 07.07.19 S7 230 225
2 St. Petersburg Rome False False 19301 04.07.2019 10.07.2019 Finnair 605 720
3 St. Petersburg Barcelona False True 20168 03.07.2019 09.07.2019 Swiss 365 355
4 St. Petersburg Barcelona True False
filter_list = [True, True, False, False, False]

Он сообщает, что последние три строки не понадобятся, а первые две надо взять. Чтобы автоматически собрать данные в срез, передадим массив как индекс датафрейма:

df[filter_list]
FromToIs_DirectHas_luggagePriceDate_FromDate_ToAirlineTravel_time_fromTravel_time_to
0 Moscow Rome False True 21032 1.07 7.07 Belavia 995 350
1 Moscow Rome True False 19250 1.07 7.07 S7 230 225
Получилось!
print(df['From'] == 'Moscow')
0     True
1     True
2    False
3    False
4    False
Name: From, dtype: bool
 
Получили знакомый булев массив, уже не вручную. Осталось выбрать строки со значением True:
print(df[df['From'] == 'Moscow']) # передаём булев массив как индекс датафрейма

    From       To     Is_Direct  Has_luggage  Price    Date_From   Date_To  Airline  \
0  Moscow  Rome      False         True        21032  01.07.19       07.07.19  Belavia   
1  Moscow  Rome       True        False        19250  01.07.19       07.07.19       S7   

   Travel_time_from  Travel_time_to  
0               995             350  
1               230             225

df[df['Price'] < 21000]
FromToIs_DirectHas_luggagePriceDate_FromDate_ToAirlineTravel_time_fromTravel_time_to
1 Moscow Rome True False 19250 01.07.19 07.07.19 S7 230 225
2 St. Petersburg Rome False False 19301 04.07.2019 10.07.2019 Finnair 605 720
3 St. Petersburg Barcelona False True 20168 03.07.2019 09.07.2019 Swiss 365 355
 
FromToIs_DirectHas_luggagePriceDate_FromDate_ToAirlineTravel_time_fromTravel_time_to
2 St. Petersburg Rome False False 19301 4.07 10.07 Finnair 605 720
 
В условиях допустимы арифметические операции. Найдём билеты, у которых дорога обратно Travel_time_to более чем в 1.5 раза быстрее, чем дорога туда Travel_time_from. 
df[1.5 * df['Travel_time_to'] < df['Travel_time_from']]
FromToIs_DirectHas_luggagePriceDate_FromDate_ToAirlineTravel_time_fromTravel_time_to
0 Moscow Rome False True 21032 1.07 7.07 Belavia 995 350
 
FromToIs_DirectHas_luggagePriceDate_FromDate_ToAirlineTravel_time_fromTravel_time_to
2 St. Petersburg Rome False False 19301 4.07 10.07 Finnair 605 720
4 St. Petersburg Barcelona True False 31425 5.07 11.07 Rossiya 255 250
 
 

             From         To  ...  Travel_time_from  Travel_time_to
1          Moscow       Rome  ...               230             225
2  St. Petersburg       Rome  ...               605             720
3  St. Petersburg  Barcelona  ...               365             355

[3 rows x 10 columns]

А вам что милее: посетить «Камп Hоу» в Барселоне или бросить монетку в римский фонтан Треви?

Результат

             From         To  ...  Travel_time_from  Travel_time_to
0          Moscow       Rome  ...               995             350
1          Moscow       Rome  ...               230             225
2  St. Petersburg       Rome  ...               605             720
3  St. Petersburg  Barcelona  ...               365             355

[4 rows x 10 columns]

Здесь вам не привычные or, and и not. Условия указывают в скобках.

Результат
     From    To  Is_Direct  ...  Airline  Travel_time_from Travel_time_to
0  Moscow  Rome      False  ...  Belavia               995            350

[1 rows x 10 columns]
Всё верно. Лишь одна строка удовлетворяет таким строгим условиям.

Срезы данных методом query()

В прошлом уроке вы делали срезы в 2 шага:

  1. Получали булев массив, соответствующий условиям.
  2. Делали срез по нему.

Это гибкий инструмент получения срезов, и владеть им полезно. Однако существует и более простой способ — метод query() (пер. «запрос»).

Необходимое условие для среза записывается в строке, которую передают как аргумент методу query(). А метод применяют к датафрейму. В результате получаем нужный срез.

import pandas as pd

df = pd.DataFrame(
    {
        'From': [
            'Moscow',
            'Moscow',
            'St. Petersburg',
            'St. Petersburg',
            'St. Petersburg',
        ],
        'To': ['Rome', 'Rome', 'Rome', 'Barcelona', 'Barcelona'],
        'Is_Direct': [False, True, False, False, True],
        'Has_luggage': [True, False, False, True, False],
        'Price': [21032, 19250, 19301, 20168, 31425],
        'Date_From': [
            '01.07.19',
            '01.07.19',
            '04.07.2019',
            '03.07.2019',
            '05.07.2019',
        ],
        'Date_To': [
            '07.07.19',
            '07.07.19',
            '10.07.2019',
            '09.07.2019',
            '11.07.2019',
        ],
        'Airline': ['Belavia', 'S7', 'Finnair', 'Swiss', 'Rossiya'],
        'Travel_time_from': [995, 230, 605, 365, 255],
        'Travel_time_to': [350, 225, 720, 355, 250],
    }
)
print(df.query('To == "Barcelona"'))

 

       From         To        Is_Direct   Has_luggage Price   Date_From  \
3  St. Petersburg  Barcelona      False         True  20168  03.07.2019   
4  St. Petersburg  Barcelona       True        False  31425  05.07.2019   

      Date_To  Airline  Travel_time_from  Travel_time_to  
3  09.07.2019    Swiss               365             355  
4  11.07.2019  Rossiya               255             250

Строки с какими индексами не будут выбраны в результате выполнения этого кода?
print(df.query('Is_Direct == True or Has_luggage == True')) 
From    To    Is_Direct    Has_luggage    Price    Date_From    Date_To    Airline    Travel_time_from    Travel_time_to
0    Moscow    Rome    False    True    21032    01.07.19    07.07.19    Belavia    995    350
1    Moscow    Rome    True    False    19250    01.07.19    07.07.19    S7    230    225
2    St. Petersburg    Rome    False    False    19301    04.07.2019    10.07.2019    Finnair    605    720
3    St. Petersburg    Barcelona    False    True    20168    04.07.2019    09.07.2019    Swiss    365    355
4    St. Petersburg    Barcelona    True    False    31425    04.07.2019    11.07.2019    Rossiya    255    250


0

1

Правильный ответ
2
Верно! Все дороги ведут в Рим, но перелёт из Санкт-Петербурга с пересадкой и без багажа — не самая приятная из них.

3

4

И даже вызывать методы:
 
df.query('Travel_time_from < Travel_time_to.mean()')
 
Ещё в query() можно включать внешние переменные (не из датафрейма). Когда упоминаете такую переменную, помечайте её знаком @:
 

             From    To  Is_Direct  ...  Airline  Travel_time_from Travel_time_to
2  St. Petersburg  Rome      False  ...  Finnair               605            720

[1 rows x 10 columns]

Записать запрос в query() легко. Просто проговорите условие:
«Has_luggage равно False» — Has_luggage == False;
«и» — and;
«Airline не равно ни S7, ни Rossiya» — Airline not in ["S7", "Rossiya"].

Результат
             From         To  ...  Travel_time_from  Travel_time_to
1          Moscow       Rome  ...               230             225
4  St. Petersburg  Barcelona  ...               255             250

[2 rows x 10 columns]

Вы уже умеете строить срезы данных целыми двумя способами. Не пора ли применить эту магию к данным по АЗС?

Для простейших графиков импортировать её не обязательно. Однако вызов библиотеки может помочь, когда вывод графиков нужно разделить. После команды вывода графика вызывают метод show(). Он позволяет посмотреть, как отличаются гистограммы с разным числом корзин:
import matplotlib.pyplot as plt
    
data.hist(bins=10)
plt.show()
data.hist(bins=100)
plt.show()

Результат
              date_time        id  time_spent      name
114797  20180402T055708  3c1e4c52     28925.0   Василёк
27147   20180406T080254  4b5f2af5     28519.0   Немезия
60547   20180408T000002  cf1ba8a5     28292.0   Василёк
19042   20180408T204208  5410e876     23696.0   Василёк
118597  20180408T165020  3c1e4c52     21184.0   Василёк
118058  20180402T111333  3c1e4c52     20359.0   Василёк
114406  20180408T083722  3c1e4c52     19886.0   Василёк
132164  20180405T160745  627ea5e3     19445.0    Левкой
281360  20180406T180459  d0c0928d     18614.0      Пион
165326  20180402T230204  3af3bb71     18569.0  Агератум

Во-первых, в столбце id разные значения, значит, долго заправляются не на одной-единственной АЗС. Во-вторых, АЗС в списке вообще из разных сетей.
Выделяется id == "3c1e4c52", он встречается несколько раз. Изучите эту АЗС детальнее.

Результат
5814
На АЗС под кодовым названием 3c1e4c52 заезжали не раз.