Пакет pandas используется для управления и анализа данных и разработан специально для работы с мечеными или реляционными данными интуитивно понятным путём.
Пакет pandas предлагает функции электронных таблиц, но в Python он намного быстрее и эффективнее, чем традиционные графические программы электронных таблиц.
Данное руководство научит вас визуализировать данные с помощью функций groupby() и pivot_table().
Читайте также: Использование пакета pandas в Python 3
Требования
Это руководство научит вас работать с данными в pandas на локальном компьютере или удалённом сервере.
- Для работы с объемными данных может потребоваться большой объем памяти, потому для выполнения руководства вам понадобится 2 Гб оперативной памяти минимум.
- Jupyter Notebook (инструкции по установке можно найти здесь).
- Среда разработки Python 3 (инструкции для CentOS 7, Windows 10, Mac OS X и Ubuntu 16.04).
Тестовые данные
В руководстве мы используем статистику детских имён с сайта социального обеспечения. Это zip-файл размером 8MB.
Разверните среду разработки Python 3 на локальной машине или на удалённом сервере.
cd environments
. my_env/bin/activate
Создайте новый каталог для проекта (пусть он называется names) и откройте его:
mkdir names
cd names
В этот каталог можно загрузить zip-файл:
curl -O https://www.ssa.gov/oact/babynames/names.zip
После этого нужно установить дополнительные пакеты:
- numpy для поддержки многомерных массивов;
- matplotlib для визуализации данных;
- pandas для анализа данных;
- seaborn, чтобы улучшить статистические графики Matplotlib.
Если какой-либо из этих пакетов ещё не установлен, установите его:
pip install pandas
pip install matplotlib
pip install seaborn
Запустите Jupyter Notebook:
jupyter notebook
Получив доступ к веб-интерфейсу Jupyter Notebook, вы увидите файл names.zip.
Чтобы создать новый документ, выберите в верхнем выпадающем меню New → Python 3.
Это откроет документ.
Импортируйте пакет. В начале документа укажите:
import numpy as np
import matplotlib.pyplot as pp
import pandas as pd
import seaborn
Чтобы запустить этот код и перейти к новому блоку, нажмите Alt + Enter.
Чтобы Python Notebook мог встраивать графики, введите:
matplotlib inline
Чтобы запустить этот код и перейти к новому блоку, нажмите Alt + Enter.
Читайте также: Использование пакета pandas в Python 3
Распаковка zip-архива
Чтобы распаковать архив в текущем каталоге, импортируйте модуль zipfile и вызовите функцию ZipFile с именем файла (names.zip).
import zipfile
zipfile.ZipFile('names.zip').extractall('.')
Чтобы запустить этот код и продолжить, нажмите Alt + Enter.
Вернитесь в каталог names, в котором теперь хранятся файлы .txt с данными с 1881 по 2015 годы в формате CSV. Названия всех файлов выбраны по одному шаблону: данные за 2015 год хранятся в yob2015.txt, а данные за 1927 – в yob1927.txt, и т.п.
Чтобы ознакомиться с форматом файла, откройте один из них в Python и запросите первые 5 строк.
open('yob2015.txt','r').readlines()[:5]
Чтобы запустить этот код и продолжить, нажмите Alt + Enter.
['Emma,F,20355\n',
'Olivia,F,19553\n',
'Sophia,F,17327\n',
'Ava,F,16286\n',
'Isabella,F,15504\n']
Как видите, сначала в файле указывается имя, затем пол (F – женский, M – мужской) и количество детей, которые получили это имя в указанном году.
Теперь нужно загрузить данные в pandas
Загрузка данных CSV в pandas
Для загрузки значений, разделенных запятыми, в pandas можно использовать функцию pd.read_csv() и передать ей имя текстового файла, а также имена столбцов. Данные можно присвоить переменной (в данном случае names2015).
names2015 = pd.read_csv('yob2015.txt', names = ['Name', 'Sex', 'Babies'])
Чтобы запустить этот код и продолжить, нажмите Alt + Enter.
Запросите начало таблицы, чтобы убедиться, что всё работает.
names2015.head()
Чтобы запустить этот код и продолжить, нажмите Alt + Enter. После этого вы увидите первые 5 строк таблицы (индексация начинается с 0).
Конкатенация объектов pandas
Конкатенация объектов позволяет работать со всем отдельными текстовыми файлами в каталоге names.
Чтобы объединить данные, инициализируйте список, присвоив переменной пустой список:
all_years = []
Читайте также: Работа со списками в Python 3
Затем используйте цикл for, чтобы проитерировать все файлы по годам в диапазоне 1880-2015. Чтобы включить 2015 в список, добавьте в диапазон +1.
all_years = []
for year in range(1880, 2015+1):
Читайте также: Циклы for в Python 3
Внутри цикла нужно добавить в список каждое значение из текстовых файлов, используя строковый форматтер для обработки имен каждого из этих файлов. Присвойте эти значения переменной year и задайте столбцы Name, Sex и Babies.
all_years = []
for year in range(1880, 2015+1):
all_years.append(pd.read_csv('yob{}.txt'.format(year),
names = ['Name', 'Sex', 'Babies']))
Также нужно создать столбец для каждого года, чтобы хранить данные в упорядоченном виде.
all_years = []
for year in range(1880, 2015+1):
all_years.append(pd.read_csv('yob{}.txt'.format(year),
names = ['Name', 'Sex', 'Babies']))
all_years[-1]['Year'] = year
Теперь нужно добавить объект pandas для конкатенации с помощью функции pd.concat(). Присвойте результат переменной all_names.
all_years = []
for year in range(1880, 2015+1):
all_years.append(pd.read_csv('yob{}.txt'.format(year),
names = ['Name', 'Sex', 'Babies']))
all_years[-1]['Year'] = year
all_names = pd.concat(all_years)
Запустите цикл с помощью Alt + Enter и проверьте вывод, вызвав последние строки получившейся таблицы.
all_names.tail()
Теперь можно приступать к работе с pandas.
Группировка данных
Пакет pandas позволяет группировать данные с помощью функции .groupby(). Набор данных, присвоенный переменной all_names, можно разделить на разные части с помощью groupby().
К примеру, можно сгруппировать данные по году или полу. Введите:
group_name = all_names.groupby(['Sex', 'Year'])
Запустите код с помощью Alt + Enter.
Затем вызовите переменную group_name, чтобы просмотреть результат:
<pandas.core.groupby.DataFrameGroupBy object at 0x1187b82e8>
Это объект DataFrameGroupBy, в котором хранятся сведения о группировке данных, но нет никакой информации о визуализации значений.
Чтобы отобразить данные в таблице, можно вычислить .size(), .mean() и .sum().
Начнём с .size():
group_name.size()
Запустите код с помощью Alt + Enter. Вы увидите:
Sex Year
F 1880 942
.....1881 938
.....1882 1028
.....1883 1054
.....1884 1172
...
Эти данные удобно читать, но с помощью функции .unstack можно оптимизировать визуализацию.
group_name.size().unstack()
Запустите код с помощью Alt + Enter. Вы увидите удобную таблицу, данные в которой упорядочены по годам и полам.
Чтобы, например, получить общее количество рожденных детей, используйте функцию .sum(). Чтобы уменьшить объем данных, примените её только к names2015 (данным за 2015 год, которые хранятся в yob2015.txt):
names2015.groupby(['Sex']).sum()
Запустите код с помощью Alt + Enter. Вы увидите таблицу, которая содержит общее число рожденных в 2015 году детей.
Сводные таблицы
Сводные таблицы помогают обобщать данные. Они могут автоматически сортировать и подсчитывать данные, а также вычислять общее или среднее значение в одной таблице. Полученные результаты можно отобразить в новой таблице.
В pandas для этого существует функция pivot_table().
Чтобы создать сводную таблицу, вызовите DataFrame, а затем вызовите и сгруппируйте данные, с которыми хотите работать.
В данном примере используем данные all_names. Отобразите данные Babies, сгруппировав их по Name и Year.
pd.pivot_table(all_names, 'Babies', 'Name', 'Year')
Запустите код с помощью Alt + Enter. Вы увидите объемную таблицу.
Поскольку на данный момент она содержит много пустых значений, лучше использовать Name и Year в качестве столбцов, а не строк. Сгруппируйте данные в квадратных скобках:
pd.pivot_table(all_names, 'Babies', ['Name', 'Year'])
Запустите код с помощью Alt + Enter. Вы увидите:
Name Year
Aaban 2007 5.0
...........2009 6.0
...........2010 9.0
...........2011 11.0
...........2012 11.0
...........2013 14.0
...........2014 16.0
...........2015 15.0
Aabha 2011 7.0
...........2012 5.0
...........2014 9.0
...........2015 7.0
Aabid 2003 5.0
Aabriella 2008 5.0
...........2014 5.0
...........2015 5.0
Также можно сгруппировать данные, где в качестве одного измерения будет Name и Sex, а в качестве второго – Year.
pd.pivot_table(all_names, 'Babies', ['Name', 'Sex'], 'Year')
Запустите код с помощью Alt + Enter. Вы увидите новую большую таблицу.
Визуализация данных
Комбинируя пакет pandas с другими пакетами, например, matplotlib, вы можете визуализировать данные внутри документа.
Давайте попробуем создать график популярности имени. Для этого нужно установить и отсортировать индексы и переработать данные, которые позволят отобразить популярность конкретного имени.
Пакет pandas позволяет выполнить иерархическую или многоуровневую индексацию, которая позволяет сохранять и управлять данными с произвольным числом измерений.
Проиндексируйте данные столбцов Sex, Name и Year, а затем отсортируйте индексы.
all_names_index = all_names.set_index(['Sex','Name','Year']).sort_index()
Запустите код с помощью Alt + Enter, а затем введите:
all_names_index
Запустите код с помощью Alt + Enter. Вы увидите объемную таблицу, в которой отображается популярность того или иного имени.
Затем нужно написать функцию, которая будет визуализировать популярность имени. Вызовите функцию name_plot и передайте sex и name в качестве параметров.
def name_plot(sex, name):
Создайте переменную data для хранения созданной таблицы. Используйте DataFrame loc, чтобы выбрать строку по значению индекса. В нашем случае loc будет использовать комбинацию полей в MultiIndex, обращаясь к данным sex и name.
Запишите в функцию такую конструкцию:
def name_plot(sex, name):
data = all_names_index.loc[sex, name]
Теперь можно отобразить значения с помощью matplotlib.pyplot, импортированного как pp.
def name_plot(sex, name):
data = all_names_index.loc[sex, name]
pp.plot(data.index, data.values)
Запустите код с помощью Alt + Enter. Теперь можно вызвать функцию и указать любое имя и пол. Например, имя Danica, пол женский (F).
name_plot('F', 'Danica')
Запустите код с помощью Alt + Enter. На экране появится график популярности данного имени в период с 1900 по 2015 год.
В некоторых системах может появиться предупреждение о замене шрифта, но данные будут отображаться правильно.
Созданная функция позволяет отобразить данные сразу о нескольких именах. Так вы можете увидеть тенденции в выборе имен в то или иное время.
Сначала нужно расширить график:
pp.figure(figsize = (18, 8))
Затем нужно создать список имён, популярность которых нужно визуализировать:
pp.figure(figsize = (18, 8))
names = ['Sammy', 'Jesse', 'Drew', 'Jamie']
После этого нужно выполнить итерацию списка с помощью цикла for и визуализировать данные о каждом имени. Выбранные нами имена могут быть как мужскими, так и женскими. Сначала соберите данные о женских именах:
pp.figure(figsize = (18, 8))
names = ['Sammy', 'Jesse', 'Drew', 'Jamie']
for name in names:
name_plot('F', name)
Добавьте легенду:
pp.figure(figsize = (18, 8))
names = ['Sammy', 'Jesse', 'Drew', 'Jamie']
for name in names:
name_plot('F', name)
pp.legend(names)
Запустите код с помощью Alt + Enter. На экране появится график популярности указанных женских имён в период с 1880 по 2015 год.
Теперь попробуйте визуализировать данные о тех же мужских именах.
pp.figure(figsize = (18, 8))
names = ['Sammy', 'Jesse', 'Drew', 'Jamie']
for name in names:
name_plot('M', name)
pp.legend(names)
Запустите код с помощью Alt + Enter. На экране появится график популярности заданных мужских имён в период с 1880 по 2015 год.
Попробуйте сами визуализировать данные по популярности или создать свой сценарий для сбора данных для графиков.
Заключение
Данное руководство охватывает основы работы с большими объёмами данных, а именно группировку данных с помощью groupby() и pivot_table(), индексацию данных в MultiIndex и визуализацию с помощью пакетов pandas и matplotlib.
Читайте также: