В этой и последующих лекциях мы будем работать с таблицами. В социальных науках термины «база данных» и «таблица» часто используются как синонимы. Вообще, между этими терминами есть существенная разница, так как база данных – это набор таблиц, связанных друг с другом (при определённых условиях можно думать о ней как о файле Excel с разными листами). Давайте для простоты считать эти термины эквивалентными, основы работы с «настоящими» базами данных (SQL, PyMongo) мы обсуждать не будем. Кроме того, в качестве синонима слова таблица мы будем использовать слово датафрейм как кальку с термина data frame.
Библиотека pandas
используется для удобной и более эффективной работы с таблицами. Её функционал достаточно разнообразен, но давайте начнем с каких-то базовых функций и методов.
Для начала импортируем саму библиотеку.
import pandas as pd
Здесь мы использовали такой приём: импортировали библиотеку и присвоили ей сокращенное имя, которое будет использоваться в пределах данного ipynb-файла. Чтобы не писать перед каждой библиотечной функцией длинное pandas.
и не импортировать сразу все функции из этой библиотеки, мы сократили название до pd
, и в дальнейшем Python будет понимать, что мы имеем в виду. Можно было бы сократить и до p
, но тогда есть риск забыть про это и создать переменную с таким же именем, что в какой-то момент приведёт к проблемам. К тому же pd
– распространенное сокращение.
(И да, таким образом можно сокращать названия любых библиотек и модулей. Ничто бы не помешало нам на предыдущих занятиях писать, например, import math as ma
, просто в этом не было необходимости).
А теперь вернемся к таблице.
А теперь давайте загрузим какую-нибудь реальную базу данных из файла. Библиотека pandas
достаточно гибкая, она позволяет загружать данные из файлов разных форматов. Пока остановимся на самом простом – файле csv, что расшифровывается как comma separated values. Столбцы в таком файле по умолчанию отделяются друг от друга запятой. Например, такая таблица
pd.DataFrame([[1, 4, 9], [4, 8, 6]])
0 | 1 | 2 | |
---|---|---|---|
0 | 1 | 4 | 9 |
1 | 4 | 8 | 6 |
сохраненная в формате csv без названий строк и столбцов будет выглядеть так:
1, 4, 9
4, 8, 6
Но разделитель столбцов в таблице может быть и другим, например, точкой с запятой:
1; 4; 9
4; 8; 6
В таких случаях нам потребуется дополнительно выставлять параметр sep = ";"
, чтобы Python понимал, как правильно отделять один столбец от другого. Но потренируемся открывать разные форматы файлов в следующий раз. Сейчас посмотрим, как загрузить файл по ссылке.
df = pd.read_csv("http://math-info.hse.ru/f/2017-18/py-prog/scores2.csv")
Для загрузки мы воспользовались функцией read_csv()
и указали сс>ылку (путь к файлу) в кавычках.
Для тех, кто чаще работает в R: следите за написанием этой функции, есть соблазн написать read.csv()
.
В файле scores2.csv
сохранены оценки студентов-политологов по ряду курсов. Оценки реальные, взяты из кумулятивного рейтинга, но имена студентов зашифрованы – вместо них задействованы номера студенческих билетов. Посмотрим на датафрейм:
df
id | catps | mstat | soc | econ | eng | polth | mstat2 | phist | law | phil | polsoc | ptheo | preg | compp | game | wpol | male | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | М141БПЛТЛ024 | 7 | 9 | 8 | 8 | 9 | 8 | 10 | 8.0 | 7 | 9 | 9 | 7.0 | 8 | 8.0 | 6 | 10 | 1 |
1 | М141БПЛТЛ031 | 8 | 10 | 10 | 10 | 10 | 10 | 10 | 9.0 | 9 | 10 | 10 | 9.0 | 8 | 8.0 | 9 | 10 | 1 |
2 | М141БПЛТЛ075 | 9 | 9 | 9 | 10 | 9 | 10 | 9 | 8.0 | 9 | 10 | 9 | 9.0 | 8 | 8.0 | 7 | 9 | 1 |
3 | М141БПЛТЛ017 | 9 | 9 | 8 | 8 | 9 | 9 | 10 | 6.0 | 9 | 9 | 9 | 8.0 | 8 | 8.0 | 8 | 9 | 0 |
4 | М141БПЛТЛ069 | 10 | 10 | 10 | 10 | 10 | 10 | 9 | 8.0 | 8 | 10 | 9 | 7.0 | 6 | 5.0 | 8 | 10 | 1 |
5 | М141БПЛТЛ072 | 10 | 9 | 8 | 10 | 9 | 8 | 9 | 8.0 | 8 | 10 | 9 | 7.0 | 8 | 8.0 | 9 | 9 | 0 |
6 | М141БПЛТЛ020 | 8 | 7 | 7 | 6 | 9 | 10 | 8 | 8.0 | 7 | 7 | 9 | 7.0 | 8 | 6.0 | 8 | 9 | 1 |
7 | М141БПЛТЛ026 | 7 | 10 | 8 | 7 | 10 | 7 | 9 | 8.0 | 8 | 8 | 8 | 8.0 | 8 | 7.0 | 7 | 8 | 0 |
8 | М141БПЛТЛ073 | 7 | 9 | 8 | 8 | 9 | 8 | 9 | 8.0 | 8 | 9 | 9 | 7.0 | 7 | 6.0 | 10 | 9 | 1 |
9 | М141БПЛТЛ078 | 6 | 6 | 9 | 5 | 6 | 10 | 7 | 6.0 | 8 | 6 | 9 | 6.0 | 8 | 8.0 | 6 | 7 | 0 |
10 | М141БПЛТЛ060 | 7 | 8 | 7 | 7 | 9 | 8 | 8 | 5.0 | 7 | 5 | 8 | 5.0 | 7 | 8.0 | 7 | 9 | 1 |
11 | М141БПЛТЛ040 | 6 | 9 | 8 | 6 | 9 | 7 | 8 | 6.0 | 9 | 5 | 8 | 5.0 | 8 | 5.0 | 7 | 10 | 0 |
12 | М141БПЛТЛ065 | 9 | 9 | 8 | 4 | 8 | 8 | 7 | 9.0 | 8 | 5 | 10 | 9.0 | 8 | 8.0 | 6 | 9 | 1 |
13 | М141БПЛТЛ053 | 6 | 7 | 7 | 5 | 9 | 8 | 7 | 8.0 | 8 | 6 | 8 | 7.0 | 8 | 6.0 | 9 | 9 | 0 |
14 | М141БПЛТЛ015 | 6 | 9 | 7 | 6 | 9 | 7 | 9 | 4.0 | 7 | 7 | 7 | 6.0 | 7 | 7.0 | 10 | 7 | 0 |
15 | М141БПЛТЛ021 | 8 | 9 | 8 | 8 | 9 | 8 | 8 | 7.0 | 7 | 7 | 6 | 6.0 | 8 | 6.0 | 7 | 8 | 0 |
16 | М141БПЛТЛ018 | 7 | 7 | 9 | 7 | 9 | 7 | 8 | 6.0 | 6 | 7 | 8 | 7.0 | 7 | 7.0 | 7 | 8 | 0 |
17 | М141БПЛТЛ039 | 9 | 8 | 9 | 8 | 8 | 8 | 6 | 8.0 | 7 | 6 | 9 | 6.0 | 7 | 8.0 | 4 | 9 | 1 |
18 | М141БПЛТЛ036 | 8 | 10 | 7 | 8 | 8 | 6 | 9 | 4.0 | 8 | 8 | 7 | 6.0 | 7 | 6.0 | 7 | 8 | 1 |
19 | М141БПЛТЛ049 | 6 | 7 | 6 | 6 | 8 | 6 | 8 | 4.0 | 8 | 5 | 9 | 6.0 | 8 | 5.0 | 6 | 8 | 0 |
20 | 06114043 | 8 | 8 | 10 | 5 | 8 | 8 | 8 | 10.0 | 7 | 7 | 9 | NaN | 7 | 8.0 | 7 | 8 | 1 |
21 | М141БПЛТЛ048 | 8 | 6 | 8 | 6 | 9 | 6 | 4 | 4.0 | 6 | 4 | 8 | 4.0 | 6 | 7.0 | 7 | 8 | 0 |
22 | М141БПЛТЛ034 | 6 | 9 | 7 | 6 | 9 | 6 | 8 | 6.0 | 7 | 6 | 6 | 5.0 | 8 | 5.0 | 8 | 9 | 0 |
23 | М141БПЛТЛ045 | 5 | 8 | 8 | 7 | 8 | 6 | 7 | 6.0 | 7 | 7 | 8 | 6.0 | 8 | 6.0 | 5 | 8 | 0 |
24 | М141БПЛТЛ033 | 5 | 9 | 8 | 7 | 9 | 7 | 9 | 7.0 | 7 | 8 | 8 | 7.0 | 8 | 5.0 | 7 | 8 | 0 |
25 | М141БПЛТЛ083 | 5 | 5 | 6 | 5 | 8 | 7 | 6 | 5.0 | 7 | 5 | 7 | 5.0 | 7 | 5.0 | 4 | 7 | 0 |
26 | М141БПЛТЛ008 | 10 | 8 | 8 | 9 | 8 | 10 | 9 | 8.0 | 9 | 10 | 9 | 8.0 | 5 | 5.0 | 10 | 4 | 1 |
27 | М141БПЛТЛ001 | 6 | 7 | 7 | 4 | 10 | 7 | 7 | 6.0 | 8 | 6 | 8 | 4.0 | 6 | 6.0 | 4 | 8 | 0 |
28 | М141БПЛТЛ038 | 7 | 9 | 6 | 4 | 9 | 6 | 7 | 6.0 | 7 | 4 | 8 | 4.0 | 5 | 4.0 | 9 | 7 | 1 |
29 | М141БПЛТЛ052 | 7 | 7 | 7 | 7 | 8 | 6 | 6 | 6.0 | 8 | 6 | 7 | 5.0 | 8 | 6.0 | 5 | 7 | 1 |
30 | М141БПЛТЛ011 | 7 | 6 | 8 | 6 | 9 | 6 | 6 | 5.0 | 6 | 6 | 7 | 6.0 | 8 | 6.0 | 5 | 8 | 0 |
31 | М141БПЛТЛ004 | 7 | 7 | 6 | 6 | 8 | 6 | 6 | 5.0 | 5 | 5 | 6 | 5.0 | 7 | 5.0 | 8 | 8 | 0 |
32 | М141БПЛТЛ010 | 6 | 6 | 7 | 6 | 9 | 7 | 7 | 6.0 | 7 | 5 | 8 | 6.0 | 8 | 6.0 | 5 | 8 | 1 |
33 | М141БПЛТЛ071 | 6 | 9 | 7 | 7 | 9 | 6 | 8 | 4.0 | 6 | 7 | 7 | 6.0 | 5 | NaN | 5 | 7 | 0 |
34 | М141БПЛТЛ035 | 5 | 6 | 7 | 6 | 8 | 5 | 5 | 4.0 | 6 | 6 | 7 | 5.0 | 8 | 7.0 | 6 | 7 | 0 |
35 | М141БПЛТЛ030 | 7 | 6 | 6 | 6 | 7 | 6 | 6 | 4.0 | 8 | 5 | 5 | 5.0 | 8 | 5.0 | 7 | 9 | 1 |
36 | М141БПЛТЛ070 | 5 | 5 | 6 | 4 | 8 | 6 | 5 | 5.0 | 6 | 4 | 5 | 6.0 | 8 | 5.0 | 6 | 7 | 0 |
37 | М141БПЛТЛ051 | 8 | 9 | 8 | 6 | 8 | 7 | 6 | 7.0 | 6 | 6 | 6 | 5.0 | 4 | 4.0 | 5 | 5 | 1 |
38 | М141БПЛТЛ046 | 5 | 7 | 7 | 4 | 7 | 5 | 8 | 5.0 | 7 | 5 | 7 | 5.0 | 8 | 4.0 | 5 | 7 | 0 |
39 | М141БПЛТЛ047 | 5 | 8 | 6 | 4 | 7 | 5 | 9 | 5.0 | 6 | 4 | 6 | 4.0 | 7 | 4.0 | 8 | 8 | 0 |
40 | М141БПЛТЛ063 | 5 | 5 | 6 | 4 | 8 | 4 | 4 | 4.0 | 5 | 4 | 5 | 4.0 | 7 | 5.0 | 8 | 8 | 0 |
41 | М141БПЛТЛ029 | 6 | 8 | 8 | 7 | 9 | 5 | 6 | 7.0 | 6 | 5 | 8 | 5.0 | 7 | 4.0 | 5 | 7 | 0 |
42 | М141БПЛТЛ064 | 7 | 8 | 6 | 7 | 6 | 6 | 8 | 4.0 | 6 | 4 | 4 | 4.0 | 6 | 5.0 | 4 | 7 | 0 |
43 | М141БПЛТЛ076 | 7 | 7 | 8 | 6 | 8 | 6 | 6 | 6.0 | 8 | 6 | 8 | 5.0 | 7 | 4.0 | 4 | 6 | 0 |
44 | М141БПЛТЛ062 | 7 | 7 | 7 | 6 | 9 | 6 | 6 | 5.0 | 6 | 5 | 6 | 4.0 | 5 | 5.0 | 4 | 6 | 0 |
45 | М141БПЛТЛ074 | 5 | 6 | 7 | 4 | 7 | 6 | 5 | 6.0 | 6 | 6 | 8 | 6.0 | 6 | 6.0 | 8 | 8 | 1 |
46 | 130232038 | 6 | 7 | 6 | 5 | 8 | 4 | 8 | 4.0 | 8 | 4 | 5 | 5.0 | 6 | 4.0 | 5 | 6 | 0 |
47 | М141БПЛТЛ023 | 7 | 9 | 6 | 8 | 9 | 6 | 9 | 4.0 | 7 | 7 | 7 | 6.0 | 4 | 4.0 | 7 | 5 | 1 |
48 | М141БПЛТЛ054 | 7 | 8 | 6 | 4 | 8 | 6 | 4 | 4.0 | 6 | 4 | 8 | 4.0 | 4 | 4.0 | 4 | 8 | 1 |
49 | М141БПЛТЛ012 | 6 | 6 | 7 | 4 | 10 | 6 | 5 | 4.0 | 7 | 5 | 7 | 4.0 | 5 | 4.0 | 4 | 8 | 1 |
50 | М141БПЛТЛ006 | 6 | 5 | 6 | 5 | 8 | 5 | 5 | 5.0 | 6 | 4 | 7 | 5.0 | 7 | 5.0 | 6 | 8 | 0 |
51 | М141БПЛТЛ055 | 6 | 5 | 6 | 4 | 7 | 7 | 4 | 8.0 | 5 | 4 | 6 | 4.0 | 6 | 5.0 | 4 | 5 | 1 |
52 | М141БПЛТЛ007 | 6 | 7 | 7 | 6 | 7 | 6 | 7 | 4.0 | 5 | 5 | 6 | 5.0 | 4 | 5.0 | 4 | 7 | 1 |
53 | М141БПЛТЛ050 | 8 | 6 | 6 | 6 | 8 | 4 | 5 | 4.0 | 5 | 5 | 6 | 4.0 | 5 | 4.0 | 6 | 6 | 0 |
54 | М141БПЛТЛ066 | 7 | 10 | 7 | 7 | 9 | 5 | 8 | 4.0 | 6 | 5 | 6 | 4.0 | 6 | 4.0 | 5 | 6 | 0 |
55 | М141БПЛТЛ043 | 5 | 5 | 6 | 5 | 8 | 5 | 6 | 5.0 | 6 | 4 | 5 | 4.0 | 5 | NaN | 4 | 6 | 0 |
56 | М141БПЛТЛ084 | 6 | 7 | 8 | 4 | 8 | 5 | 5 | NaN | 8 | 4 | 4 | 4.0 | 4 | 4.0 | 6 | 7 | 1 |
57 | М141БПЛТЛ005 | 5 | 7 | 5 | 5 | 7 | 4 | 7 | 4.0 | 5 | 4 | 5 | 5.0 | 4 | 4.0 | 4 | 8 | 1 |
58 | М141БПЛТЛ044 | 4 | 5 | 7 | 4 | 6 | 4 | 4 | 5.0 | 4 | 4 | 4 | 4.0 | 6 | NaN | 5 | 5 | 1 |
59 | 13051038 | 5 | 4 | 4 | 4 | 9 | 5 | 5 | 5.0 | 5 | 4 | 4 | NaN | 7 | 4.0 | 4 | 4 | 1 |
Так как в нашем случае таблица не очень большая, Python вывел ее на экран полностью. Если строк или столбцов было бы слишком много, Python вывел бы несколько первых и последних, а в середине бы поставил многоточие.
Описание показателей (переменных):
Так как «в обычной жизни» за рамками курса данные редко загружаются по готовой и удобной ссылке, давайте потренируемся загружать таблицы из локальных файлов на компьютере.
По умолчанию Python видит только те файлы, которые хранятся в текущей рабочей папке – папке, откуда запускается Python или, в нашем случае, Jupyter Notebook. Чтобы узнать, какая папка является рабочей, необходимо загрузить модуль os
и вызвать функцию getcwd()
:
import os # от operating system
os.getcwd() # от get current working directory
'/Users/allat/Desktop'
Эта функция возвращает путь к рабочей папке. В моем случае это '/Users/allat/Desktop
, на компьютере с Windows в классе ‒ C:\\Users\\student
. Python подсказывает, что в моем случае рабочей папкой является Рабочий стол, который лежит в папке oem, в home. Обратите внимание: в Mac OS и Linux слэши между названиями папок прямые и одинарные, в Windows – обратные и двойные. Плюс, в Windows всегда в начале прописывается диск (C:
или иные). На вид слэшей нужно всегда обращать внимание: Python не воспринимает одинарные обратные слэши \
и будет ругаться, если мы пропишем путь к файлу с ними. Их нужно заменить на прямые слэши /
, и тогда всё будет хорошо.
Иногда удобно положить файл, с которым мы будем работать, в рабочую папку. Можно явно переместить файл из папки в папку, но при работе в Jupyter можно сделать проще – воспользоваться кнопкой Upload на странице Home. Кто пользуется командной строкой, есть альтернатива: запустить сам Jupyter Notebook из той папки, где хранятся файлы для работы.
А так можно изменить рабочую папку, прописав новый путь (обратите внимание, папка должна существовать; если ее нет, Python не создаст её автоматически, а выдаст ошибку):
os.chdir("/Users/allat/Downloads")
Теперь перейдем к загрузке самого файла. Не всегда удобно перемещать файл в рабочую папку или изменять путь к рабочей папке. Иногда проще прописать путь к самому файлу. Если неясно, как он должен выглядеть, всегда можно узнать, скопировав расположение файла из Свойств, кликнув правой клавишей на файл (не забудьте после пути к файлу указать название файла с расширением и обратите внимание на слэши).
df = pd.read_csv("scores2.csv")
Какую сводную информацию по таблице можно получить? Например, число переменных (столбцов) и наблюдений (строк), а также число заполненных значений.
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 60 entries, 0 to 59 Data columns (total 18 columns): id 60 non-null object catps 60 non-null int64 mstat 60 non-null int64 soc 60 non-null int64 econ 60 non-null int64 eng 60 non-null int64 polth 60 non-null int64 mstat2 60 non-null int64 phist 59 non-null float64 law 60 non-null int64 phil 60 non-null int64 polsoc 60 non-null int64 ptheo 58 non-null float64 preg 60 non-null int64 compp 57 non-null float64 game 60 non-null int64 wpol 60 non-null int64 male 60 non-null int64 dtypes: float64(3), int64(14), object(1) memory usage: 8.5+ KB
Какую информацию выдал метод .info()
? Во-первых, он сообщил нам, что df
является объектом DataFrame. Во-вторых, он вывел число строк (60 entries
) и показал их индексы (М141БПЛТЛ024 to 13051038
). В-третьих, он вывел число столбцов (total 17 columns
). Наконец, он выдал информацию по каждому столбцу. Остановимся на этом поподробнее.
В выдаче выше представлено, сколько непустых элементов содержится в каждом столбце. Непустые элементы non-null
– это всё, кроме пропущенных значений, которые кодируются особым образом (NaN
– от * Not A Number). В нашей таблице почти все столбцы заполнены полностью: 60 ненулевых элементов из 60. Но есть столбцы с пропущенными значениями: phist, ptheo, compp*.
Далее указан тип каждого столбца, целочисленный int64
и с плавающей точкойfloat64
. Что означают числа в конце? Это объем памяти, который требуется для хранения.
Сводную статистическую информацию можно получить с помощью метода .describe()
.
df.describe()
catps | mstat | soc | econ | eng | polth | mstat2 | phist | law | phil | polsoc | ptheo | preg | compp | game | wpol | male | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 60.000000 | 60.000000 | 60.000000 | 60.000000 | 60.000000 | 60.000000 | 60.000000 | 59.000000 | 60.000000 | 60.000000 | 60.000000 | 58.000000 | 60.000000 | 57.000000 | 60.000000 | 60.000000 | 60.000000 |
mean | 6.700000 | 7.466667 | 7.216667 | 6.116667 | 8.350000 | 6.600000 | 7.033333 | 5.830508 | 6.866667 | 5.966667 | 7.183333 | 5.603448 | 6.700000 | 5.631579 | 6.250000 | 7.566667 | 0.450000 |
std | 1.417804 | 1.578099 | 1.208608 | 1.718214 | 0.971195 | 1.638519 | 1.707081 | 1.662492 | 1.213856 | 1.850027 | 1.589069 | 1.413465 | 1.356716 | 1.422166 | 1.781496 | 1.430499 | 0.501692 |
min | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 6.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 4.000000 | 0.000000 |
25% | 6.000000 | 6.000000 | 6.000000 | 5.000000 | 8.000000 | 6.000000 | 6.000000 | 4.000000 | 6.000000 | 4.750000 | 6.000000 | 4.250000 | 6.000000 | 4.000000 | 5.000000 | 7.000000 | 0.000000 |
50% | 7.000000 | 7.000000 | 7.000000 | 6.000000 | 8.000000 | 6.000000 | 7.000000 | 6.000000 | 7.000000 | 5.500000 | 7.000000 | 5.000000 | 7.000000 | 5.000000 | 6.000000 | 8.000000 | 0.000000 |
75% | 7.250000 | 9.000000 | 8.000000 | 7.000000 | 9.000000 | 8.000000 | 8.000000 | 7.000000 | 8.000000 | 7.000000 | 8.000000 | 6.000000 | 8.000000 | 7.000000 | 7.250000 | 8.250000 | 1.000000 |
max | 10.000000 | 10.000000 | 10.000000 | 10.000000 | 10.000000 | 10.000000 | 10.000000 | 10.000000 | 9.000000 | 10.000000 | 10.000000 | 9.000000 | 8.000000 | 8.000000 | 10.000000 | 10.000000 | 1.000000 |
В случае количественных показателей этот метод возвращает таблицу с основными описательными статистиками: