- •Python для науки о данных: перезагрузка Ремикс популярной книги Генри Гарнера "Clojure для науки о данных", 2015
- •Об авторе оригинала книги
- •Содержание
- •Предисловие автора к оригиналу книги на Clojure
- •Статистика
- •Скачивание исходного кода примеров
- •Обследование данных
- •Исправление данных
- •Описательные статистики
- •Среднее значение
- •Интерпретация математических обозначений
- •Медиана
- •Дисперсия
- •Квантили
- •Дискретизация данных
- •Гистограммы
- •Нормальное распределение
- •Центральная предельная теорема
- •Булочник господина Пуанкаре
- •Генерирование распределений
- •Асимметрия
- •Графики нормального распределения
- •Способы сопоставительной визуализации
- •Коробчатые диаграммы
- •Интегральные функции распределения
- •Важность визуализации
- •Визуализация данных об электорате
- •Обработка столбцов
- •Добавление производных столбцов
- •Сопоставительная визуализация электоральных данных
- •Визуализация электоральных данных рф
- •Сравнительная визуализация
- •Функции массы вероятности
- •Точечные графики
- •Настройка прозрачности разброса
Добавление производных столбцов
Чтобы выяснить, какой процент электората проголосовал за одну из двух партий, требуется вычислить сумму голосов, отданных за каждую из них. Для этого нам понадобится создать новое поле данных Victors (Победители) из данных, которые соответствуют Консервативной (Con) и Либерально-демократической (LD) партиям и заодно проверим, имеются ли пропущенные значения.
def ex_1_26():
'''Вычислить производное поле данных "Победители" и
число имеющихся в нем пропущенных значений'''
df = load_uk_scrubbed()
df['Победители'] = df['Con'] + df['LD']
freq = Counter(df['Con'].apply( lambda x: x > 0 ))
print('Поле "Победители": %d, в т.ч. пропущено %d'
% (freq[True], freq[False]))
# Поле "Победители": 631, в т.ч. пропущено 19
Результат показывает, что в 19 случаях даные отсутствуют. Очевидно, что в каком-то из столбцов: столбце Con либо столбце LD (либо обоих), данные отсутствуют, но в каком именно? Снова воспользуемся словарем Counter, чтобы увидеть масштаб проблемы:
'''Проверить пропущенные значения в полях
"Консервативная партия" (Con) и
"Либерально-демократическая партия" (LD)'''
df = load_uk_scrubbed()
Counter(df['Con'].apply(lambda x: x > 0)),
Counter(df['LD'].apply(lambda x: x > 0))
# (Counter({False: 19, True: 631}), Counter({False: 19, True: 631}))
В обоих случаях будет выведено одинаковое число строк, в которых значения есть, и в которых они отсутствуют. Воспользуемся предикативной функцией isnull, которую мы уже встречали ранее в этой главе, чтобы узнать, какие строки не содержат значений:
def ex_1_27():
'''Выборка полей данных по условию, что поля
"Консервативная партия" (Con) и
"Либерально-демократическая" (LD) не пустые'''
df = load_uk_scrubbed()
rule = df['Con'].isnull() & df['LD'].isnull()
return df[rule][['Region', 'Electorate', 'Con', 'LD']]
|
Region |
Electorate |
Con |
LD |
12 |
Northern Ireland |
60204.0 |
NaN |
NaN |
13 |
Northern Ireland |
73338.0 |
NaN |
NaN |
14 |
Northern Ireland |
63054.0 |
NaN |
NaN |
… |
… |
… |
… |
… |
584 |
Northern Ireland |
64594.0 |
NaN |
NaN |
585 |
Northern Ireland |
74732.0 |
NaN |
NaN |
Небольшое обследование данных должно определить причину, почему эти поля оказались пустыми. Как оказалось, кандидаты в соответствующих избирательных округах не выдвигались. Следует ли эти строки отфильтровать или же оставить как есть, равными нулю? Это интересный вопрос. Давайте их отфильтруем, поскольку вообще-то невозможно, чтобы в этих округах избиратели выбрали какого-либо кандидата, неважно от либеральных демократов или консерваторов. Если же мы напротив допустили, что они равны нулю, то среднее количество людей, которое — при заданных вариантах выбора — проголосовало за одну из этих партий, было бы искусственно занижено.
Зная, как фильтровать проблемные строки, теперь добавим производные столбцы, которые будут представлять победителя, долю голосов за победителя и явку на выборы. Отфильтруем строки так, чтобы показать только те, где были выдвинуты кандидаты от обеих партий:
def load_uk_victors():
'''Загрузить данные по Великобритании,
выбрать поля и отфильтровать'''
df = load_uk_scrubbed()
rule = df['Con'].notnull()
df = df[rule][['Con', 'LD', 'Votes', 'Electorate']]
df['Победители'] = df['Con'] + df['LD']
df['Доля победителей'] = df['Победители'] / df['Votes']
df['Явка'] = df['Votes'] / df['Electorate']
return df
В результате в нашем наборе данных теперь имеется три дополнительных столбца: Victors, Victors Share и Turnout, т.е. победители, доля победителей и явка на выборы. Покажем на квантильном графике долю голосов за победителя, чтобы увидеть, как она соотносится с теоретическим нормальным распределением:
def ex_1_28():
'''Показать квантильный график победителей
на выборах в Великобритании'''
qqplot( load_uk_victors()['Доля победителей'] )
plt.show()
Приведенный выше пример создаст следующий график:
Основываясь на сводном графике разных форм кривых квантильных графиков, показанном ранее в этой главе, можно заключить, что доля голосов, отданных за победителя, имеет "легкие хвосты" по сравнению с нормальным распределением. Это означает, что ближе к среднему значению расположено больше данных, чем можно было бы ожидать, исходя из действительно нормально распределенных данных.
