Следующая тема: ИАД. Изучение срезов данных
Вернуться в раздел: Исследовательский анализ данных
Вернуться в оглавление: Я.Практикум
1. Введение
3. Сводные таблицы для расчета среднего
7. Гистограмма
8. Гистограмма для двух кубиков
11. Диаграмма размаха в Python
12. Описание данных
13. Заключение
14. Проверочные задания. Первые графики и выводы
Знакомство с задачей
Как исследовать поведение водителей на заправках, если вы — Яндекс? Обратиться к статистике Яндекс.Навигатора: узнать, на какую именно заправку заезжал водитель и сколько времени там провёл.
Ваши коллеги из Навигатора собрали необходимые данные и прислали их в таком виде:
- Зашифрованное наименование сети АЗС (столбец
name
): вместо брендов — названия растений. - Уникальный идентификатор конкретной АЗС (столбец
id
) — в сети их много. - Время заезда на АЗС (столбец
date_time
) в формате ISO: 20190405T165358 означает, что водитель прибыл на заправку 5 апреля 2019 года в 16 часов 53 минуты 58 секунд по UTC. - Проведённое на АЗС время (столбец
time_spent
) в секундах.
Нужно ответить на вопрос, сколько в среднем времени тратят водители на заправку в каждой из сетей АЗС. Выведем первые строки таблицы методом head():
import pandas as pd
data = pd.read_csv('/datasets/visits.csv')
print(data.head())
date_time\tid\ttime_spent\tname
0 20190405T165358\t76144fb2\t98.0\tВасилёк
1 20190403T173913\t76144fb2\t15.0\tВасилёк
2 20190402T172824\t76144fb2\t220.0\tВасилёк
3 20190406T070441\t76144fb2\t19.0\tВасилёк
4 20190403T132049\t76144fb2\t14.0\tВасилёк
Вот и первая проблема. Данные склеились в одну строку вместо того, чтобы разбиться по колонкам. Это произошло из-за разделителей в формате csv
. Напомним, что csv
— это Comma-Separated Values, или значения, разделённые запятыми. Действительно, в прошлых уроках вы работали с таблицами, где строку на колонки делили запятые. Однако вместо них могут быть точки с запятой, знаки табуляции или другие символы. Могут вносить путаницу и десятичные дроби, записанные с запятой. Какими символами разделять колонки и дроби, указывают в аргументах функции read_csv()
. За разделитель колонок отвечает параметр sep
(от англ. separate — «отделять, разделять»), а дробей — параметр decimal
(пер. «десятичная дробь»):
file = pd.read_csv('file.csv', sep=';', decimal=',')
6 ноября 1974 года пуэрториканская обсерватория Аресибо отправила в космос радиосигнал, вошедший в историю под названием «Послание Аресибо».
Это адресованная инопланетянам информация, записанная двоичным кодом: числа от 1 до 10; химические элементы; строение и форма ДНК; количество людей на Земле, их средний рост и эскиз устройства человека; описание Солнечной системы; сведения об обсерватории Аресибо. Фрагмент послания выглядит так: Само послание — последовательность нулей и единиц. Для расшифровки нужно разбить её на 73 строки по 23 символа. Вызовем функцию read_csv()
— обратите внимание, что ей можно «скормить» файл в формате txt
— и прочитаем послание Аресибо:
arecibo = pd.read_csv('arecibo.txt')
print(arecibo.head())
1\2\3\4\5\6\7\8\9\10\11\12\13\14\15\16\17\18\19\20\21\22\23
0 0\0\0\0\0\0\1\0\1\0\1\0\1\0\0\0\0\0\0\0\0\0\0
1 0\0\1\0\1\0\0\0\0\0\1\0\1\0\0\0\0\0\0\0\1\0\0
2 1\0\0\0\1\0\0\0\1\0\0\0\1\0\0\1\0\1\1\0\0\1\0
3 1\0\1\0\1\0\1\0\1\0\1\0\1\0\1\0\0\1\0\0\1\0\0
4 0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
Послание выглядит совсем не так, как хотелось. Разделитель — обратный слэш \
. В Python один обратный слэш \
используют для команд: например, \n
— перевод строки. Чтобы не перепутать, пишут двойной: \. Прочитаем послание ещё раз с учётом разделителя столбцов:
arecibo = pd.read_csv('arecibo.txt', sep='\\')
print(arecibo.head())
1 2 3 4 5 ... 19 20 21 22 23
0 0 0 0 0 ... 0 0 0 0 0
1 0 0 1 0 ... 0 0 1 0 0
2 1 0 0 0 ... 1 0 0 1 0
3 1 0 1 0 ... 0 0 1 0 0
4 0 0 0 0 ... 0 0 0 0 0
Теперь единицы и нули строка за строкой можно превратить в квадратики, которые прочтут инопланетяне. А мы возвращаемся из дальнего космоса на бензоколонку.
Задача
Прочитайте файл visits.csv
из папки /datasets/
, указав в качестве разделителя знак табуляции \t
, и сохраните результат в датафрейме data
. Выведите его первые пять строк.
Путь к файлу: /datasets/visits.csv
import pandas as pd
data = pd.read_csv('/datasets/visits.csv', sep='\t')
print (data.head(5))
date_time id time_spent name
0 20180406T165358 76144fb2 98.0 Василёк
1 20180404T173913 76144fb2 15.0 Василёк
2 20180403T172824 76144fb2 220.0 Василёк
3 20180407T070441 76144fb2 19.0 Василёк
4 20180404T132049 76144fb2 14.0 Василёк
Когда что-то не клеится — это обычно нехорошо. Когда данные не склеиваются в одну строку — это, наоборот, здорово.
Сводные таблицы для расчёта среднего¶
Нужно узнать, сколько времени в среднем водители тратят на заправку в каждой сети АЗС. В каждой строке датафрейма есть название сети и время, проведённое на АЗС. Занимаясь предобработкой данных, вы применяли pivot_table()
— метод для построения сводных таблиц.
Напомним его параметры:
index
— столбец, значения которого становятся названиями строк (индексом);columns
— столбец, значения которого становятся названиями столбцов;values
— значения, по которым вы хотите увидеть сводную таблицу;aggfunc
— функция, применяемая к значениям.
Прежде значением aggfunc
вы указывали sum
, то есть складывали элементы столбца. Если параметр aggfunc не указывать, то по умолчанию метод pivot_table()
рассчитает среднее арифметическое значений, указанных в параметре values
.
Чтобы начать работать с данными о заправках, надо сначала научиться строить сводные таблицы. Для этого у вас будет новый набор данных — с информацией о матчах Национальной хоккейной лиги.
Нужно проанализировать среднюю посещаемость домашних матчей команд Национальной хоккейной лиги, начиная с сезона 2000–2001 гг. и заканчивая сезоном 2017–2018 гг. Посмотрим на первые пять строк таблицы, где для каждой команды указано количество домашних матчей и их суммарная посещаемость home_att
:
nhl_att = pd.read_excel('nhl_attendance.xlsx')
print(nhl_att.head())
season team home_games home_att
0 2017-2018 Chicago 41 887794
1 2017-2018 Montreal 41 873283
2 2017-2018 Philadelphia 41 800214
3 2017-2018 Detroit 41 800115
4 2017-2018 Toronto 41 786677
Найдём среднюю посещаемость домашних матчей для команды:
nhl_att['avg_home_att'] = nhl_att['home_att'] / nhl_att['home_games']
print(nhl_att.head())
nhl_pivot = nhl_att.pivot_table(index='season', values='avg_home_att')
# группируем таблицу по сезонам, для каждого находим среднюю посещаемость
print(nhl_pivot)
2000-01 16559.268467
2001-02 16758.941463
2002-03 16590.563415
2003-04 16549.755285
2005-06 16954.608943
2006-07 16960.798374
2007-08 17307.805691
2008-09 17476.049593
2009-10 17072.668333
2010-11 17122.738211
2011-12 17455.410569
2012-13 17720.623611
2013-14 17587.389431
2014-15 17502.595122
2015-16 17576.266667
2016-17 17500.631707
2017-18 17446.312352
Какие выводы можно сделать, прочитав эту таблицу?
Наибольшая средняя посещаемость матчей была в сезоне 2012-2013 гг.
Можно наблюдать тренд к снижению средней посещаемости с сезона 2012-2013 гг.
Начиная с сезона 2007-2008 гг. средняя посещаемость не была ниже 17 000 зрителей.
Правильный ответ Всё вышеперечисленное верно.
Применяем сводные таблицы
Наибольшая средняя посещаемость матчей была в 2012–2013 гг. Примечательно, что в тот сезон состоялось только 48 игр вместо традиционных 82. Недостачу вызвали трудовые споры между руководством лиги и профсоюзом хоккеистов.
Начиная с сезона 2007–2008 гг. средняя посещаемость никогда не была ниже 17 000 зрителей. Значит, маркетинг лиги работает.
Наконец, в последние сезоны наблюдался тренд к снижению средней посещаемости. Это может быть связано с тем, что некоторые команды стали играть на малых стадионах.
Суровый бой ведёт ледовая дружина, а мы застряли на АЗС.
Задача
Сводные таблицы используют на разных этапах работы с данными. Можно начать с оценки данных и посчитать среднее время заправки в секундах. Нужные значения хранит столбец time_spent
.
- С помощью
pivot_table()
вычислите среднее время, проведённое на заправках в каждой из сетей, и сохраните результат в переменнуюstat
. - Выведите на экран значение переменной
stat
и проанализируйте полученные данные. Не забудьте, чтоtime_spent
хранит значения в секундах.
import pandas as pd
data = pd.read_csv ('/datasets/visits.csv', sep='\t')
stat = data.pivot_table(index='name', values='time_spent')
print (stat)
time_spent
name
Агератум 337.802721
Амарант 132.760012
Аммобиум 256.708042
Арктотис 73.879984
Астильба 376.143149
Бальзамин 134.508411
Бархатцы 145.300328
Бегония 163.200647
Белоцветник 100.818966
Есть ли проблемы в данных?
Таблицу, которую получили в прошлом уроке, нельзя показывать менеджерам: они всё равно не поверят!
У сетей АЗС «Нарцисс», «Арктотис» и «Малопа» среднее время заправки около 70 секунд. Неправдоподобно мало.
Как вы думаете, всё ли в порядке с данными?
Всё правильно посчитано, в результатах не может быть ошибки.
Правильный ответ Всё может быть. Нужно проверить и данные, и расчёты.
Надо искать ошибку в расчётах.
Наверное, нам прислали неправильные данные.
Доверяй, но проверяй. В следующем уроке начнём проверять данные.
Базовая проверка данных
В работе с данными почти всегда вас ждут сюрпризы:
- Почему-то выгрузили не те данные или не всё, что есть.
- Ошибки в алгоритмах, считающих заезды: скажем, время заправки учли неверно.
- Не тот формат: например, вместо секунд записали минуты.
- Упущен какой-нибудь существенный факт. Так, водители могли заехать на нерабочую АЗС (а счётчик их учёл) и развернуться, не заправившись (счётчик зафиксировал очень короткое время). Словом, в данных может быть всё что угодно. Именно вы как аналитик ручаетесь за их реалистичность. Попробуйте оценить, насколько они достоверны. Начните с базовых проверок. Например, можно ответить на вопросы:
- Сколько всего заездов зафиксировано за время исследования?
- Сколько АЗС?
- Сколько заездов на одну АЗС в день?
- Какие сети АЗС самые популярные? ...И самостоятельно либо с помощью коллег оценить, похожи ли результаты ваших расчётов на правду.
Базовая проверка может обнаружить проблему в данных. Или наоборот — свидетельствовать, что с ними всё в порядке. По крайней мере, пока.
Задача 1/5
Сперва найдите количество заездов на АЗС. Одна строка в датафрейме соответствует одному посещению, значит, нужно посчитать строки.
Сохраните количество строк датафрейма в переменную total_visits
. Результат выведите на экран так:
Количество заездов: ...
import pandas as pd
data = pd.read_csv ('/datasets/visits.csv', sep='\t')
#количество заездов на АЗС
total_visits = data['id'].count()
print('Количество заездов:', total_visits)
Количество заездов: 317104
Хорошо бы понимать, насколько это число реалистично. С чем его можно соотнести? Можно посчитать среднее количество заездов на одну АЗС в день. Чтобы получить среднее, нужно найти количество АЗС и число дней, по которым есть данные.
Задача 2/5
Теперь нужно понять, сколько АЗС в данных. У каждой станции есть свой номер — id
. Чтобы найти количество АЗС, посчитайте уникальные id
.
Сохраните количество АЗС в переменной total_stations
, результат выведите на экран так:
Количество АЗС: ...
import pandas as pd
data = pd.read_csv ('/datasets/visits.csv', sep='\t')
#количество заездов на АЗС
total_visits = data['id'].count()
#print('Количество заездов:', total_visits)
total_stations = len(data['id'].unique())
print('Количество АЗС:', total_stations)
Количество заездов: 317104 Количество АЗС: 471
Эксперты говорят, что это число близко к числу всех АЗС в регионе. Хороший сигнал! Все АЗС охватили и не насчитали лишнего.
Задача 3/5
Аналитику могут сообщить, за какой срок собрали данные. Эту информацию лучше перепроверить. Понадобится столбец date_time
, который хранит время прибытия водителей на АЗС.
Выведите минимальное и максимальное значения столбца date_time
через пробел, вызвав функцию print()
только один раз. Добавлять к выводу дополнительный текст или сохранять значения в переменные не нужно.
import pandas as pd
data = pd.read_csv ('/datasets/visits.csv', sep='\t')
#количество заездов на АЗС
total_visits = data['id'].count()
print('Количество заездов:', total_visits)
total_stations = len(data['id'].unique())
print('Количество АЗС:', total_stations)
print(data['date_time'].min(), data['date_time'].max())
Количество заездов: 317104
Количество АЗС: 471
20180402T000008 20180408T235957
Наблюдения происходили с 00:00:08 2 апреля 2018 года (20180402T000008) по 23:59:57 8 апреля 2018 года (20180408T235957). Сколько это дней?
Задача 4/5
Записи в столбце date_time
хранятся в формате ISO:
YYYYMMDDTHHMMSS
. T — разделитель между датой и временем. В предыдущей задаче вы обнаружили, что первая дата прибытия на АЗС — 2 апреля 2018 года в 00:00, а последняя — 8 апреля 2018 года в 23:59. Значит, данные покрывают семь дней. Теперь можно найти среднее количество посещений АЗС за день.
- Сохраните в переменную
total_days
количество дней. - В переменную
station_visits_per_day
запишите среднее количество визитов на АЗС за день. Чтобы посчитать среднее, используйте значения переменныхtotal_visits
,total_stations
иtotal_days
. Выведите на экран значение переменной в таком виде:
Количество заездов на АЗС в сутки: ...
import pandas as pd
data = pd.read_csv ('/datasets/visits.csv', sep='\t')
#количество заездов на АЗС
total_visits = data['id'].count()
print('Количество заездов:', total_visits)
total_stations = len(data['id'].unique())
print('Количество АЗС:', total_stations)
print(data['date_time'].min(), data['date_time'].max())
total_days = round(((pd.to_datetime(data['date_time'].max(), format='%Y%m%dT%H%M%S') - pd.to_datetime(data['date_time'].min(), format='%Y%m%dT%H%M%S'))/pd.Timedelta("1s")/60/60/24))
station_visits_per_day = total_visits/total_stations/total_days
print ('Количество заездов на АЗС в сутки:', station_visits_per_day)
Количество заездов: 317104
Количество АЗС: 471
20180402T000008 20180408T235957
Количество заездов на АЗС в сутки: 96.17955717318775
Почти 100 заездов на АЗС с включённым Яндекс.Навигатором в день. Похоже ли это на правду? Можно допустить, что на АЗС заправляется от одной до пяти машин в минуту. Ночью — меньше. Если взять среднюю оценку: одна машина в минуту — это 1440 заездов в сутки. Выходит, с включённым Яндекс.Навигатором на заправку заезжает меньше 10% водителей. Тогда число в 100 заездов кажется близким к истине. Вроде бы с объёмом данных всё в порядке.
Задача 5/5
Вы только что нашли среднее количество заездов за день. Но будьте осторожны со средними значениями. На них влияет даже небольшое количество экстремально малых или больших значений в данных. Поэтому важно смотреть на общее распределение.
Проверьте распределение числа заездов по сетям АЗС. Можно ожидать, что больше заездов будет на популярных станциях.
Выведите на экран 10 сетей АЗС с наибольшим количеством заездов, вызвав метод value_counts()
для нужного столбца. Метод автоматически отсортирует данные по убыванию количества посещений, поэтому дополнительная сортировка не понадобится.
- Посчитайте количество уникальных значений в столбце name.
- Убедитесь, что данные отсортированы в порядке убывания, и выведите первые 10 строк.
import pandas as pd
data = pd.read_csv ('/datasets/visits.csv', sep='\t')
#количество заездов на АЗС
total_visits = data['id'].count()
print('Количество заездов:', total_visits)
total_stations = len(data['id'].unique())
print('Количество АЗС:', total_stations)
print(data['date_time'].min(), data['date_time'].max())
total_days = round(((pd.to_datetime(data['date_time'].max(), format='%Y%m%dT%H%M%S') - pd.to_datetime(data['date_time'].min(), format='%Y%m%dT%H%M%S'))/pd.Timedelta("1s")/60/60/24))
station_visits_per_day = total_visits/total_stations/total_days
print ('Количество заездов на АЗС в сутки:', station_visits_per_day)
print(data['name'].value_counts().head(10))
Количество заездов: 317104
Количество АЗС: 471
20180402T000008 20180408T235957
Количество заездов на АЗС в сутки: 96.17955717318775
Календула 85648
Василёк 79006
Георгина 34356
Немезия 20138
Колокольчик 18835
Мальва 17386
Гейхера 14125
Доротеантус 6312
Нарцисс 3640
Амарант 3221
Name: name, dtype: int64
Эксперты рынка АЗС подтвердили, что сети «Календула» и «Василёк» — крупнейшие игроки. Другие сети, по словам специалистов, также распределились правдоподобно.
Поздравляем! С объёмом данных всё в порядке. Нужно разбираться дальше.
Гистограмма
На первый взгляд данные выглядят корректно.
Однако есть гипотеза, что продолжительность заправки посчитана неверно: в некоторых сетях это время выглядит неправдоподобно маленьким. Напомним, вы считали среднее арифметическое. Оно не означает, что столько времени заправляются все водители: кто-то больше, кто-то меньше. Как представить себе значения, из которых рассчитано среднее, если в таблице тысячи строк? Не просматривать же каждую. Для ответа на этот вопрос строят гистограмму.
Гистограмма — это график, который показывает, как часто в наборе данных встречается то или иное значение. Гистограмма объединяет числовые значения по диапазонам, то есть считает частоту значений в пределах каждого интервала. Её построение подобно работе знакомого вам метода value_counts()
, подсчитывающего количество уникальных значений в списке. value_counts()
группирует строго одинаковые величины и хорош для подсчёта частоты в списках с категориальными переменными.
Сравните гистограмму с результатом работы метода value_counts()
на примере данных о «Симпсонах» — знаменитом американском мультсериале. В 2021 году выходит уже 33-й сезон и 716-й эпизод. «Симпсоны» дважды вошли в Книгу рекордов Гиннесса: как самый длинный ситком в истории и как телевизионный сериал с наибольшим количеством приглашённых звёзд.
В датасете информация об эпизодах «Симпсонов»: название, дата выхода на экран, сезон, номер в сезоне и рейтинг. Стоит ли авторам и продюсерам сериала готовить новый сезон?
Помогите команде принять решение. Найдите рейтинг эпизодов сериала в прошлом.
simpsons = pd.read_csv('simpsons.csv')
print(simpsons.head())
id title season \
0 10 Homer's Night Out 1
1 12 Krusty Gets Busted 1
2 14 Bart Gets an "F" 2
3 17 Two Cars in Every Garage and Three Eyes on Eve... 2
4 19 Dead Putting Society 2
number_in_season imdb_rating
0 10 7.4
1 12 8.3
2 1 8.2
3 4 8.1
4 6 8.0
Методом value_counts()
можно вывести количество серий, получивших тот или иной рейтинг:
print(simpsons['imdb_rating'].value_counts())
7.3 48
7.0 42
7.1 42
6.9 40
7.2 39
6.7 29
8.2 29
7.7 27
8.0 25
6.6 23
6.8 21
6.5 18
8.3 18
7.5 18
8.1 18
...
Ай, карамба! Такое представление данных никак не убедит продюсеров продолжать работу над «Симпсонами». Чтобы увидеть, какие оценки сериал получал чаще всего, можно построить гистограмму:
Чаще всего эпизоды получали оценки в районе 7 баллов и выше. Это очень хороший показатель для сериала. The show must go on!
В pandas гистограмму строит специальный метод hist()
(от англ. histogram — «гистограмма»). Применять его можно к списку или к столбцу датафрейма: во втором случае название столбца передаётся в параметре. Метод hist()
находит в наборе чисел минимальное и максимальное значения, а полученный диапазон делит на области, или корзины. Затем hist()
считает, сколько значений попало в каждую корзину, и отображает это на графике.
Параметр bins
(пер. «корзины, вёдра») определяет, на сколько областей делить диапазон данных. По умолчанию таких «корзин» 10.
Построим гистограмму, отображающую количество шаров в боулинге. Допустим, у нас по одному шару каждого номера от 6 до 16:
import pandas as pd
# строим гистограмму
pd.Series([6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]).hist()
Хотя на каждый номер приходится один шар, гистограмма не похожа на прямоугольник. Это потому, что по умолчанию параметр bins=10
, а шаров 11. Передадим соответствующее число корзин и взглянем на полученный график:
pd.Series([6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]).hist(bins=11)
Теперь гистограмма соответствует действительности. Что, если количество шаров с разными номерами изменится? Скажем, будет два шара под номером 8 и ни одной «семёрки»?
pd.Series([6, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16]).hist(bins=11)
Провал там, где должно быть значение 7. Частота появления восьмёрки увеличилась вдвое. График выглядит правдоподобно.
Что произойдёт, если в данных шестнадцатый шар вдруг станет шаром под номером 100, а пятнадцатый пропадёт вовсе?
pd.Series([6, 8, 8, 9, 10, 11, 12, 13, 14, 100]).hist()
# убрали параметр bins, так как шаров стало 10
Девять шаров со значениями в диапазоне от 5 до 15 и один шар с номером от 90 до 100. При таком изображении не видно тонких особенностей распределения значений в диапазоне от 5 до 15 — того, что в нём нет семёрки, а восьмёрок пара. Вернём детальность, увеличив число корзин до 100.
pd.Series([6, 8, 8, 9, 10, 11, 12, 13, 14, 100]).hist(bins=100)
На этом графике видно, что восьмёрка удвоена, а семёрка не встречается вовсе. Увеличив число корзин, мы вернули детализацию, однако гистограмма всё ещё не наглядна. 100 слишком похоже на выброс — значение, сильно отличающееся от других элементов в наборе данных.
Изменим масштаб вручную, указав диапазон значений, по которым следует строить график. Границы интересующего интервала указывают в параметре range (пер. «диапазон»): range=(min_value, max_value). Нужна область от 6 до 14:
pd.Series([6, 8, 8, 9, 10, 11, 12, 13, 14, 100]).hist(range = (6, 14))
Гистограмма даёт представление о структуре данных. В частности, по ней можно понять, откуда взялось такое среднее арифметическое. Вот 2 ряда по 10 чисел: их гистограммы очень разные, а среднее у обеих 5.
pd.Series([0, 0, 0, 0, 0, 10, 10, 10, 10, 10]).hist(range=(0, 10))
pd.Series([4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6]).hist(range=(0, 10))
Если смотреть только на среднее значение этих наборов данных, можно сказать, что они очень похожи. Однако описывающие их гистограммы дают понять, что это два очень разных явления. В интерактивной иллюстрации ниже вы можете самостоятельно построить гистограммы для разного количества случайных значений и корзин:
Пора применить гистограмму к реальной задаче. Напомним, что средняя продолжительность заправки выглядит неправдоподобно малой.
Задача 1/3
Медианные и средние значения недостаточно характеризуют данные. Настало время посмотреть на распределение значений. Постройте гистограмму по значениям времени, проведённого на АЗС. Эти значения хранятся в столбце time_spent
.
import pandas as pd
data = pd.read_csv ('/datasets/visits.csv', sep='\t')
data['time_spent'].hist()
Почти все значения собрались в одном столбце. По такой гистограмме особо ничего и не скажешь.
Задача 2/3
Предыдущая гистограмма выглядит странно, потому что максимальное значение столбца time_spent сильно превышает большинство других значений. Измените код, чтобы гистограмма стала более информативной.
Постройте новую гистограмму и увеличьте число корзин до 100.
Задача 3/3
Итак, гистограмма стала более информативной. Можно исключить слишком большие значения времени заправки и посмотреть на остальные. Используйте параметр range
, чтобы изучить распределение значений time_spent
, находящихся в диапазоне от 0 до 1500. Количество корзин оставьте прежним — 100.
import pandas as pd
data = pd.read_csv ('/datasets/visits.csv', sep='\t')
#data['time_spent'].hist()
#data['time_spent'].hist(bins=100)
data['time_spent'].hist(bins=100, range = (0,1500))
льтат
Мощный узкий пик около 0 секунд. Широкий пик около 200 секунд. Очень мало значений после 1000 секунд, но отдельные выбросы были и до 30000 секунд. Как же интерпретировать эти данные?
Гистограмма для двух кубиков
Аналитик должен представлять себе гистограмму ожидаемого вида, чтобы знать, когда стоит насторожиться. Для некоторых явлений можно выяснить все возможные значения и описать частоту их появления — это называется «распределение».
Отвлекитесь от задачи про АЗС и пофантазируйте. Представьте два игральных кубика с шестью гранями. Мысленно подбросьте их.
Единственная комбинация, дающая 12 очков в сумме, — это две шестёрки. А 8 можно получить разными способами: 2 и 6; 3 и 5; 4 и 4. Из-за того, что таких наборов больше, получить восьмёрку более вероятно, чем 12.
Теперь представьте, как подкидываете пару кубиков не один, а 1000 раз! Какие комбинации получатся тогда? Не бойтесь сложных задач — всё возможно, когда есть воображение.
Если вам недостаёт фантазии или умения держать 1000 чисел в голове одновременно, напишите функцию в Python. Она выдаст все возможные комбинации с их частотой, по ним-то вы и построите гистограмму.
Для генерации случайных чисел в Python вызывают библиотеку random (пер. «случайный»):
import random
Функция random.randint()
(от англ. random integer — «случайное целое число») возвращает случайные целые числа. Она принимает два аргумента: самое маленькое и самое большое допустимое число. Посмотрите, как она работает:
print(random.randint(1, 5))
print(random.randint(1, 5))
print(random.randint(1, 5))
print(random.randint(1, 5))
print(random.randint(1, 5))
1 5 2 4 5
score = random.randint(1, 6)
# от англ. dice — «кубик»,
# roll — «бросок»
def dice_roll():
score = random.randint(1, 6)
return score
print(dice_roll())
print(dice_roll())
print(dice_roll())
Напишем функцию, возвращающую случайное число точек на верхней грани:
# от англ. dice — «кубик»,
# roll — «бросок»
def dice_roll():
score = random.randint(1, 6)
return score
print(dice_roll())
print(dice_roll())
print(dice_roll())
1
2
5
У нас пара кубиков. Значит, нужна функция, получающая количество очков от броска двух кубиков:
# от англ. double – «двойной», roll – «бросок», score – «очки»
def double_roll_score():
first = dice_roll()
second = dice_roll()
score = first + second
return score
print(double_roll_score())
print(double_roll_score())
print(double_roll_score())
4
8
7
Сделаем 1000 таких бросков и построим гистограмму полученных очков:
import pandas as pd
# Cоздаём пустой список. В него
# попадут результаты экспериментов.
experiments = []
for i in range(1000):
score = double_roll_score()
# Напомним: метод append() добавляет новый
# элемент score в конец списка experiments.
experiments.append(score)
df_experiments = pd.DataFrame(experiments)
df_experiments.hist(bins=11, range=(2, 12))
Интересно, такая гистограмма описывает только броски кубиков или характерна для других явлений?
Задача 1/2
Будем бросать на стол 10 монет и считать количество выпавших орлов. Функции для имитации одного броска и подсчёта числа орлов в нескольких бросках уже в прекоде. Мы повторили эксперимент 1000 раз и сохранили результат в переменной df_experiments
.
Постройте гистограмму полученных значений с диапазоном значений от 0 до 11 и количеством корзин 11.
import random
import pandas as pd
# Функция, имитирующая один бросок монеты.
# От англ. coin - монета, flip - бросок монеты.
def coin_flip():
# возможны два варианта:
# - выпала решка, это +0 орлов
# - выпал орёл, это +1 орёл
score = random.randint(0, 1)
return score
# Функция для суммирования числа орлов в нескольких бросках.
# Орёл и решка переводятся на английский как heads и tails.
# Аргумент repeat говорит, сколько раз бросать монету
# (от англ. repeat - повторение).
def flips_heads(repeat):
total = 0
for i in range(repeat):
flip = coin_flip()
total += flip
return total
# Cоздаём пустой список. В него мы
# будем складывать результаты экспериментов.
experiments = []
for i in range(1000):
score = flips_heads(10)
# Напомним: функция append() добавляет новый
# элемент score в конец списка experiments.
experiments.append(score)
# превращаем список в DataFrame
df_experiments = pd.DataFrame(experiments)
# постройте гистограмму для df_experiments
df_experiments.hist(bins=11, range=(0, 11))
Чаще всего выпадает 5 орлов и совсем редко — 10 и 0. Орёл — птица гордая: пока не подкинешь, не выпадет.
Задача 2/2
Валерик каждый день едет на работу с тремя пересадками: сперва на автобусе до метро; затем по одной ветке, а потом по другой; и от метро добирается до работы на автобусе. Валерик знает, сколько продолжается поездка на каждом виде транспорта и пересадки, но вечно забывает учесть ожидание автобусов и поездов. Постройте гистограмму опозданий Валерика за 5 лет c параметром bins=10
.
Будем считать, что автобус прибывает за время от 0 до 10 минут, а поезд — за время от 0 до 5 минут. В прекоде мы уже написали функции, которые это имитируют.
import random
import pandas as pd
# Функция, имитирующая время ожидания автобуса.
# (от англ. bus - автобус, wait - ждать, time - время)
def bus_wait_time():
return random.randint(0, 10)
# Функция, имитирующая время ожидания поезда в метро.
# (от англ. train - поезд, wait - ждать, time - время)
def train_wait_time():
return random.randint(0, 5)
# Функция подсчёта полного опоздания за день.
# от англ. total - полный, итоговый, delay - задержка, опоздание
def total_delay():
# обратите внимание, как в Python переносят длинные строки
return (
bus_wait_time()
+ train_wait_time()
+ train_wait_time()
+ bus_wait_time()
)
# создайте пустой список
days = []
for i in range(365 * 5):
delay = total_delay()
# добавьте опоздание в список days
days.append(delay)
# превращаем список в DataFrame
df_days = pd.DataFrame(days)
# постройте гистограмму для df_days
df_days.hist(bins=10)
В среднем Валерик опаздывает на работу на джентльменские 15 минут. Однако бывает, что и на полчаса! Но редко. Почти так же редко, как и приходит вовремя. Быть может, подарить Валерику джентльменские часы?
Распределения
Взгляните ещё раз на гистограммы кубиков, орлов и опозданий Валерика. Из-за того, что функция подбора случайных чисел каждый раз работает по-разному, ваши гистограммы могут немного отличаться от тех, которые вы сейчас увидите.
Гистограмма суммы очков при броске пары кубиков:
Гистограмма количества орлов при бросках монет:
Гистограмма опозданий Валерика:
Наиболее частые (типичные, нормальные) значения оказываются посередине. А редкие — по краям. График симметричен и напоминает колокол. Такое распределение называется нормальным.
Нормальные или тяготеющие к ним распределения распространены в жизни. Так распределяется рост людей, размер яблок, результаты измерения температуры. Понимание природы распределений необходимо для обнаружения важных аномалий.
Так, измеряя длину изготовленных на заводе деталей, мы ожидаем распределение, тяготеющее к нормальному. Если же в результате расчётов получили распределение, скажем, с двумя пиками, это должно насторожить аналитика. Такое может быть, если на заводе есть две производственные линии и с одной из них приходят данные в сантиметрах, а с другой — в метрах.
В общем случае любое отклонение от ожидаемого распределения — это сигнал, что данные не в порядке.
Ещё одно распределение, которое часто встречается, — распределение Пуассона. Оно описывает число событий в единицу времени.
Например, в среднем в магазин заходит два человека в минуту. Но это не значит, что каждую минуту заходит ровно два человека. Может, в эту минуту не зайдёт ни одного, а через минуту зайдёт пять. Если каждый посетитель заходит случайным образом, независимо от других, то это и есть распределение Пуассона:
Форма распределения Пуассона зависит от числа событий. При небольших значениях распределение смещено влево, а с увеличением числа событий становится симметричным и уходит вправо.
Невозможно получить отрицательное число заходов в магазин, но при небольшом потоке посетителей есть шанс, что в определённую минуту придут пять посетителей или не придёт ни одного. В таком случае распределение Пуассона обрезано на нуле и имеет длинный «хвост» в положительную сторону. При увеличении числа посетителей шанс не получить ни одного захода в магазин уже почти не реализуется, поэтому распределение Пуассона становится симметричным и стремится к нормальному.
💡 Есть и другие типичные распределения, кроме нормального и Пуассона. Каждое из них по-своему полезно, и все можно подробно изучить на курсе «Математика для анализа данных» в Практикуме.
Диаграмма размаха
Вспомните распределение времени на АЗС, которое получили в седьмом уроке.
data['time_spent'].hist(bins=100, range=(0, 1500));
Как вы интерпретируете такое распределение?
Всё ожидаемо, есть пик на малых временах и длинный хвост на больших.
Правильный ответ Странно, что есть пик около 0.
Как вы интерпретируете такое распределение?
Всё ожидаемо, есть пик на малых временах и длинный хвост на больших.
Правильный ответ Странно, что есть пик около 0.
Ожидаемое распределение времени заправки — гистограмма с длинным хвостом на высоких значениях и падением в ноль слева от пика, не доходя до нулевого времени заправки. Однако на графике виден высокий пик около 0. Скорее всего, он имеет иную природу. Это не заправки, а ошибки расчётов, проезды сквозь АЗС или что-то ещё.
Описывая распределение, аналитики рассчитывают среднее арифметическое или медиану. С соответствующими методами mean()
и median()
вы познакомились в курсе по предобработке данных. Однако, помимо медианы и среднего, важно знать характерный разброс — то, какие значения оказались вдали от среднего и насколько их много.
Самое простое, что можно посчитать для оценки разброса, — это минимальное и максимальное значения. Такое описание не всегда точно, подвержено влиянию выбросов. Гораздо более устойчивая оценка — межквартильный размах.
Квартили (от лат. quartus — «четвёртый») разбивают упорядоченный набор данных на четыре части. Первый квартиль Q1 — число, отделяющее первую четверть выборки: 25% элементов меньше, а 75% — больше него. Медиана — второй квартиль Q2, половина элементов больше и половина меньше неё. Третий квартиль Q3 — это отсечка трёх четвертей: 75% элементов меньше и 25% элементов больше него. Межквартильный размах — это расстояние между Q1 и Q3.
Чему равен Q1 в выборке из пяти значений 1, 6, 10, 25, 100?
1
Правильный ответ 6
3
8
10
Увидеть медиану и квартили в Python можно на специальном графике. Его называют диаграммой размаха или «ящиком с усами».
«Ящик» ограничен первым и третьим квартилями. Внутри ящика обозначают медиану.
«Усы» простираются влево и вправо от границ ящика на расстояние, равное 1,5 межквартильного размаха (сокращённо IQR, от англ. interquartile range, «межквартильный размах»). В размах «усов» попадают нормальные значения, а за пределами находятся выбросы, изображённые точками. Если правый «ус» длиннее максимума, то он заканчивается максимумом. То же — для минимума и левого «уса».
Диаграмма размаха в Python
В Python диаграмму размаха строят методом boxplot()
(от англ. box-and-whisker plot — «график „ящик с усами“»).
Посмотрим, как выглядит график для данных задачи про АЗС:
Не очень наглядно. Видно, что есть выбросы, и многие почти до 30000 секунд, однако на этом всё. Чтобы лучше разглядеть «ящик с усами», изменим масштаб графика.
Для продвинутой работы с графиками (в том числе гистограммами) импортируют библиотеку matplotlib
(от англ. math — «математический», plot — «график, диаграмма», library — «библиотека»). Желая построить график, обращаются к методам pandas, а он, в свою очередь, передаёт данные matplotlib. При вызове функций рисования pandas возвращает оси графика. Ими можно управлять, задавая ограничения на оси абсцисс (x) и оси ординат (y).
Применим метод ylim(y_min, y_max)
(от англ. y-limits — «пределы по оси ординат») для изменения масштаба по вертикальной оси. Если требуется поменять масштаб по горизонтальной оси, вызывают метод xlim(x_min, x_max)
(от англ. х-limits — «пределы по оси абсцисс»). У обоих методов два параметра: минимальное и максимальное желаемые значения для графика. Методы вызывают из библиотеки matplotlib.
import matplotlib.pyplot as plt
plt.ylim(-50, 500)
plt.xlim(0, 200)
Метод boxplot() позволяет визуально оценить характеристики распределения, не прибегая к гистограмме. Удобно, когда нужно сравнить разные выборки.
Задача
Нарисуйте диаграмму размаха для data, ограничив диапазон по вертикали значениями -100 и 1000.
import matplotlib.pyplot as plt
import pandas as pd
data = pd.read_csv ('/datasets/visits.csv', sep='\t')
data.boxplot()
plt.ylim(-100, 1000)
plt.show()
Можно увидеть, что большая часть значений лежит в диапазоне до 300 секунд, что выглядит правдоподобно. Но при этом 1-й квартиль лежит на уровне менее 50 секунд, а это подозрительно.
Описание данных
Сравните повёрнутую набок гистограмму и «ящик с усами» из прошлого урока. Найдите медиану и квартили; внимательно изучите «усы».
Нижний «ус» упирается в 0, минимальное значение. Верхний заканчивается около 650 секунд — это 1,5 межквартильного размаха, добавленного к 3-му квартилю. Это ориентировочная граница нормального размаха. Всё, что лежит за ней, считается выбросом. Более высокие значения рисуются отдельными точками, но сливаются в единую жирную линию: таких выбросов очень много.
И всё же значения, которые отсёк верхний «ус», — редкие. Видно, насколько медиана (зелёная линия) не стремится к длинному хвосту высоких значений.
Заметные на гистограмме нюансы распределения хорошо бы зафиксировать в числах: иметь под рукой среднее, медиану, количество наблюдений в выборке и разброс их значений. Такие характеристики, дающие представление о выборке, входят в числовое описание данных. В Python его получают методом describe()
(пер. «описать, охарактеризовать»). Результат работы метода — список характерных значений:
print(data.describe())
count 3.0 # количество наблюдений в наборе данных
mean 2.0 # среднее арифметическое
std 1.0 # стандартное отклонение
min 1.0 # минимальное значение
25% 1.5 # первый квартиль
50% 2.0 # медиана, или второй квартиль
75% 2.5 # третий квартиль
max 3.0 # максимальное значение
dtype: float64 # тип данных
Описание данных может быть не только дополнением к графикам, но и самодостаточной боевой единицей первичного анализа. Если в данных много столбцов или нужно сравнить несколько выборок, аналитики обращаются к числовому описанию, а не к графикам.
Изучите полученный в результате работы describe()
список характерных значений. Какое из них вы ещё не проходили?
Стандартное отклонение — единственное значение, которого мы ещё не касались. Оно характеризует разброс величин и показывает, насколько значения в выборке отличаются от среднего арифметического.
Бывает, что именно стандартное отклонение позволяет понять природу распределения и выяснить, насколько значения однородны. Выборка, где все значения близки к среднему, будет охарактеризована малым стандартным отклонением. Если же стандартное отклонение велико, в наборе данных могут быть серьёзные аномалии или выбросы.
К примеру, проанализируем успеваемость двух учеников. Вот списки характерных значений школьных оценок того и другого:
Оценки Виктора Середнячко
count 11.000000
mean 4.090909
std 0.700649 # значения в списке отличаются от среднего на 0.7
min 3.000000
25% 4.000000
50% 4.000000
75% 4.500000
max 5.000000
dtype: float64
Оценки Ивана Контрастова
count 11.000000
mean 4.090909
std 1.375103 # значения в списке отличаются от среднего почти на 1,4
min 2.000000
25% 3.000000
50% 5.000000
75% 5.000000
max 5.000000
dtype: float64
Средний балл у обоих — 4,09. Если исходить только из него, кажется, что Виктор с Иваном получают примерно похожие отметки, да и учатся, скорее всего, одинаково.
Но посмотрите на стандартное отклонение — 0,7 у Виктора и 1,4 у Ивана. В два раза больше! Судя по стандартному отклонению, успеваемость у них распределяется по-разному. Оценки Виктора тяготеют к четвёрке, тогда как у Ивана отклонение от среднего столь велико, что четвёрок он мог и не получать. Изучим классный журнал:
Середнячко Виктор: 4, 4, 5, 3, 4, 4, 4, 5, 3, 4, 5
Контрастов Иван: 5, 5, 5, 5, 5, 5, 5, 4, 2, 2, 2
Мы оказались правы! Виктор в основном получал четвёрки и время от времени — тройки и пятёрки. Иван же знал предмет на отлично, внезапно превратился в двоечника, а «среднюю» четвёрку получал только раз. Это повод для отдельного исследования: что стряслось с Иваном? Он влюбился, попал в плохую компанию или просто заскучал?
Задача
Правильно истолковать значения на диаграмме размаха трудно, особенно когда границы оси Y — это 0 и 1000. Можно сравнить числовое описание, которое выдаёт метод describe()
, с диаграммой размаха. Так вы графически отобразите распределение данных и зафиксируете важные значения в числах. Обратите внимание, что значения 25%
и 75%
в выдаче метода describe()
— это Q1 и Q3 соответственно.
Примените к таблице data
метод describe()
и выведите на экран список характерных значений.
import pandas as pd
data = pd.read_csv ('/datasets/visits.csv', sep='\t')
print(data.describe())
Результат
time_spent
count 317104.000000
mean 203.382294
std 395.754791
min 0.000000
25% 19.000000
50% 108.000000
75% 274.000000
max 28925.000000
Обратите внимание, что среднее почти в два раза больше медианы. Значит, в распределении есть длинный хвост с высокими значениями или несколько очень больших значений. Это влияет на среднее, но не на медиану.
Заключение
В этой теме вы узнали, что такое распределение, познакомились с базовой проверкой данных, научились строить гистограммы. Они понадобятся ещё не раз там, где исследование даст неожиданные результаты.
Вы сильно продвинулись в решении поставленной бизнесом задачи: сколько времени тратят водители на АЗС. Уже рассчитали среднюю продолжительность заправки методом pivot_table()
, проверили распределение числа заездов по сетям станций и распечатали топ-10 с наибольшим заездом. Сколько всего! Но самое важное — научились проверять данные и расчёты на правдоподобность и находить неочевидные аномалии. В этом заслуга вас и распределений :-)
Раз добрались до аномалий, пора взять на вооружение срез данных. Что это такое — в следующей теме.
Заберите с собой
Чтобы ничего не забыть, скачайте шпаргалку и конспект темы.
Где ещё почитать про гистограммы, ящик с усами и описательную статистику
Описательные статистики: среднее, медиана, стандартное отклонение, перцентили
Проверочные задания. Первые графики и выводы
Чтобы пройти тест нужно правильно ответить на 5 вопросов из 10.
Время на прохождение: 20 минут
Задание 1 из 10
У метода read_csv() есть параметр sep, в котором задают разделитель колонок датафрейма. Какой символ указать при чтении CSV-файла?
sep='|'
sep=','
sep='\t'
Правильный ответ
Выбор символа зависит от того, какой разделитель использован в данных.
Значения в CSV-файле чаще всего разделены запятыми. Но так бывает не всегда: разделителями могут быть также знаки '\t' или ';'. Если ваши данные при чтении склеились в одну строку — проверьте, какой символ использован в данных.
Задание 2 из 10
Нужно проанализировать данные Национальной баскетбольной ассоциации и построить несколько графиков. Для какой задачи подойдёт гистограмма?
Сравнить распределение значений роста у игроков разных десятилетий и проанализировать медиану, первый и третий квартили.
Правильный ответ
Визуализировать распределение очков команд-победителей и найти диапазон самых распространённых значений.
Нарисовать график, который отобразит количество игроков из разных стран, и сравнить количество игроков из Австралии и Канады.
Гистограмма поможет оценить форму распределения и частоту каждого очка в наборе данных. Самое высокое значение на гистограмме — самое распространённое. Но для визуализации медианы или общего количества значений по категориям гистограмма не подойдёт.
Задание 3 из 10
Нужно проанализировать данные Национальной баскетбольной ассоциации и построить несколько графиков. Для какой задачи подойдёт диаграмма размаха?
Правильный ответ
Отобразить распределение значений роста у игроков за последние десять лет и проанализировать медиану, первый и третий квартили.
Визуализировать распределение очков проигравших команд и найти диапазон самых распространённых значений.
Нарисовать график, который отобразит количество побед десяти самых успешных команд.
Для отображения медианы и квартилей строят специальный график — диаграмму размаха. На гистограмме можно попытаться найти медиану, но точного значения такой график не даст.
Задание 4 из 10
Соотнесите номер на графике с тем, что он обозначает.
image
1
Медиана
2
Пределы нормальных значений
3
Выбросы
4
Межквартильный размах
Диаграмма размаха — непростой график. Нужно знать, как такой график устроен, чтобы интерпретировать результат. Диаграмму размаха ещё иногда называют «ящик с усами». На графике действительно есть «ящик»: он ограничен первым и третьим квартилями и отображает межквартильный размах. «Ящик» раздёлен линией — это медиана. «Усами» на графике отмечены пределы нормальных значений. За пределами «усов» находятся выбросы, изображённые точками.
Задание 5 из 10
Какое значение называют вторым квартилем (Q2)?
Самое частотное значение в данных.
Число, которое отделяет первую четверть выборки.
Число, которое отделяет последнюю четверть выборки.
Правильный ответ
Число, которое разделяет выборку пополам.
Квартили разделяют данные на четверти. Первый квартиль отделяет первую четверть, второй — две четверти или половину. Второй квартиль выборки — это медиана.
Задание 6 из 10
Чем является число 3 в объекте data? Возможно несколько ответов.
data = pd.DataFrame([1, 2, 3, 4, 5])
Правильный ответ
Медианным значением
Тоже правильный ответ
Средним значением
Стандартным отклонением
Первым квартилем
Медиана и среднее в этой выборке совпадают, но так бывает редко. Напомним, что стандартное отклонение характеризует разброс значений. В объекте data значения отличаются от среднего на 1.58. Получить стандартное отклонение и другие числовые характеристики выборки можно методом describe().
Задание 7 из 10
Выберите верные утверждения.
Правильный ответ
Если стандартное отклонение высокое, в данных могут быть выбросы.
В первом датасете значение среднего меньше, чем во втором. Стандартное отклонение в первом датасете тоже будет меньше.
В двух датасетах одинаковое среднее, но в первом 100 наблюдений, а во втором — 1000. В первом датасете стандартное отклонение будет меньше.
Правильный ответ
Если в данных все значения одинаковые, стандартное отклонение будет равно нулю.
Стандартное отклонение не зависит от среднего или объёма выборки. Сравните: в списке [3, 5, 7] среднее меньше, чем в списке [7, 7, 7]. Но стандартное отклонение первого списка больше. Другой пример: в списке [3, 5, 7] меньше значений, чем в списке [5, 5, 5, 5]. Но значения в первом списке сильнее отличаются от среднего.
Задание 8 из 10
Колонка age в датафрейме data хранит количественные значения. Нужно построить гистограмму, которая отобразит распределение значений в колонке age в диапазоне от 18 до 30. Какой код построит такую гистограмму?
Правильный ответ
data.hist('age', range=(18, 30))
data.hist('age', bins=(18, 30))
data.hist('age', bins=18, range=30)
data.hist('age', (18, 30))
Нужные значения диапазона передают в аргументе range. Параметр bins управляет «корзинами» — количеством областей, на которые разделятся данные. Если передать значения диапазона в аргументе, не указав bins или range, Python интерпретирует их как позиционный аргумент и передаст второму аргументу метода. Из документации следует, что это будет параметр by, который управляет группировкой.
Задание 9 из 10
Выберите метод, который построит диаграмму размаха.
hist()
Правильный ответ
boxplot()
plot()
whiskerplot()
Диаграмму размаха иногда называют «ящиком с усами» (англ. box and whisker plot) и строят методом boxplot(). Жаль, нет метода whiskerplot(): «усатый график» довольно говорящее название.
Задание 10 из 10
Выберите код, который ограничит масштаб графика значениями 100 и 1000 по вертикали.
Правильный ответ
import matplotlib.pyplot as plt
plt.ylim(100, 1000)
import matplotlib.pyplot as plt
plt.xlim(100, 1000)
from pandas import plt
plt.ylim(100, 1000)
from pandas import plt
plt.xlim(100, 1000)
Методы ylim() и xlim() вызывают из библиотеки matplotlib. Эта библиотека вам не раз пригодится в работе с графиками. Метод ylim() меняет масштаб по вертикали или, иначе, оси ординат, а метод xlim() — по горизонтали или оси абсцисс.
Следующая тема: ИАД. Изучение срезов данных
Вернуться в раздел: Исследовательский анализ данных
Вернуться в оглавление: Я.Практикум