#!/usr/bin/env python # coding: utf-8 # # Основы программирования в Python # # *Алла Тамбовцева, НИУ ВШЭ* # # ## Работа с таблицами. Введение в библиотеку `pandas` # ### Датафреймы (таблицы) # В этой и последующих лекциях мы будем работать с таблицами. В социальных науках термины «база данных» и «таблица» часто используются как синонимы. Вообще, между этими терминами есть существенная разница, так как база данных – это набор таблиц, связанных друг с другом (при определённых условиях можно думать о ней как о файле Excel с разными листами). Давайте для простоты считать эти термины эквивалентными, основы работы с «настоящими» базами данных (*SQL*, *PyMongo*) мы обсуждать не будем. Кроме того, в качестве синонима слова *таблица* мы будем использовать слово *датафрейм* как кальку с термина *data frame*. # Библиотека `pandas` используется для удобной и более эффективной работы с таблицами. Её функционал достаточно разнообразен, но давайте начнем с каких-то базовых функций и методов. # # Для начала импортируем саму библиотеку. # In[1]: import pandas as pd # Здесь мы использовали такой приём: импортировали библиотеку и присвоили ей сокращенное имя, которое будет использоваться в пределах данного ipynb-файла. Чтобы не писать перед каждой библиотечной функцией длинное `pandas.` и не импортировать сразу все функции из этой библиотеки, мы сократили название до `pd`, и в дальнейшем Python будет понимать, что мы имеем в виду. Можно было бы сократить и до `p`, но тогда есть риск забыть про это и создать переменную с таким же именем, что в какой-то момент приведёт к проблемам. К тому же `pd` – распространенное сокращение. # # (И да, таким образом можно сокращать названия любых библиотек и модулей. Ничто бы не помешало нам на предыдущих занятиях писать, например, `import math as ma`, просто в этом не было необходимости). # # А теперь вернемся к таблице. # ### Загрузка таблицы из файла и описание переменных # # А теперь давайте загрузим какую-нибудь реальную базу данных из файла. Библиотека `pandas` достаточно гибкая, она позволяет загружать данные из файлов разных форматов. Пока остановимся на самом простом – файле *csv*, что расшифровывается как *comma separated values*. Столбцы в таком файле по умолчанию отделяются друг от друга запятой. Например, такая таблица # In[2]: pd.DataFrame([[1, 4, 9], [4, 8, 6]]) # сохраненная в формате *csv* без названий строк и столбцов будет выглядеть так: # 1, 4, 9 # 4, 8, 6 # Но разделитель столбцов в таблице может быть и другим, например, точкой с запятой: # 1; 4; 9 # 4; 8; 6 # В таких случаях нам потребуется дополнительно выставлять параметр `sep = ";"`, чтобы Python понимал, как правильно отделять один столбец от другого. Но потренируемся открывать разные форматы файлов в следующий раз. Сейчас посмотрим, как загрузить файл по ссылке. # In[3]: df = pd.read_csv("http://math-info.hse.ru/f/2017-18/py-prog/scores2.csv") # Для загрузки мы воспользовались функцией `read_csv()` и указали сс>ылку (путь к файлу) в кавычках. # # *Для тех, кто чаще работает в R:* следите за написанием этой функции, есть соблазн написать `read.csv()`. # В файле `scores2.csv` сохранены оценки студентов-политологов по ряду курсов. Оценки реальные, взяты из кумулятивного рейтинга, но имена студентов зашифрованы – вместо них задействованы номера студенческих билетов. Посмотрим на датафрейм: # In[4]: df # Так как в нашем случае таблица не очень большая, Python вывел ее на экран полностью. Если строк или столбцов было бы слишком много, Python вывел бы несколько первых и последних, а в середине бы поставил многоточие. # **Описание показателей (переменных):** # # * id – номер студенческого билета # * catps – оценка по курсу *Категории политической науки* # * mstat – оценка по курсу *Математика и статистика* # * soc – оценка по курсу *Социология* # * econ – оценка по курсу *Экономика* # * eng – оценка по курсу *Английский язык* # * polth – оценка по курсу *История политических учений* # * mstat2 – оценка по курсу *Математика и статистика (часть 2)* # * phist – оценка по курсу *Политическая история* # * law – оценка по курсу *Право* # * phil – оценка по курсу *Философия* # * polsoc – оценка по курсу *Политическая социология* # * ptheo – оценка по курсу *Политическая теория* # * preg – оценка по курсу *Политическая регионалистика* # * compp – оценка по курсу *Сравнительная политика* # * game – оценка по курсу *Теория игр* # * wpol – оценка по курсу *Мировая политика и международные отношения* # * male – пол (1 ‒ мужской, 0 ‒ женский) # Так как «в обычной жизни» за рамками курса данные редко загружаются по готовой и удобной ссылке, давайте потренируемся загружать таблицы из локальных файлов на компьютере. # По умолчанию Python видит только те файлы, которые хранятся в текущей рабочей папке – папке, откуда запускается Python или, в нашем случае, Jupyter Notebook. Чтобы узнать, какая папка является рабочей, необходимо загрузить модуль `os` и вызвать функцию `getcwd()`: # In[5]: import os # от operating system # In[6]: os.getcwd() # от get current working directory # Эта функция возвращает путь к рабочей папке. В моем случае это `'/Users/allat/Desktop`, на компьютере с Windows в классе ‒ `C:\\Users\\student`. Python подсказывает, что в моем случае рабочей папкой является *Рабочий стол*, который лежит в папке *oem*, в *home*. Обратите внимание: в Mac OS и Linux слэши между названиями папок прямые и одинарные, в Windows – обратные и двойные. Плюс, в Windows всегда в начале прописывается диск (`C:` или иные). На вид слэшей нужно всегда обращать внимание: Python не воспринимает одинарные обратные слэши `\` и будет ругаться, если мы пропишем путь к файлу с ними. Их нужно заменить на прямые слэши `/`, и тогда всё будет хорошо. # Иногда удобно положить файл, с которым мы будем работать, в рабочую папку. Можно явно переместить файл из папки в папку, но при работе в Jupyter можно сделать проще – воспользоваться кнопкой *Upload* на странице *Home*. Кто пользуется командной строкой, есть альтернатива: запустить сам Jupyter Notebook из той папки, где хранятся файлы для работы. # # А так можно изменить рабочую папку, прописав новый путь (обратите внимание, папка должна существовать; если ее нет, Python не создаст её автоматически, а выдаст ошибку): # In[7]: os.chdir("/Users/allat/Downloads") # Теперь перейдем к загрузке самого файла. Не всегда удобно перемещать файл в рабочую папку или изменять путь к рабочей папке. Иногда проще прописать путь к самому файлу. Если неясно, как он должен выглядеть, всегда можно узнать, скопировав расположение файла из *Свойств*, кликнув правой клавишей на файл (не забудьте после пути к файлу указать название файла с расширением и обратите внимание на слэши). # In[8]: df = pd.read_csv("scores2.csv") # Какую сводную информацию по таблице можно получить? Например, число переменных (столбцов) и наблюдений (строк), а также число заполненных значений. # In[9]: df.info() # Какую информацию выдал метод `.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()`. # In[10]: df.describe() # В случае количественных показателей этот метод возвращает таблицу с основными описательными статистиками: # # * count – число непустых (заполненных) значений # * mean – среднее арифметическое # * std – стандартное отклонение (показатель разброса данных относительно среднего значения) # * min – миниммальное значение # * max – максимальное значение # * 25% – нижний квартиль (значение, которое 25% значений не превышают) # * 50% – медиана (значение, которое 50% значений не превышают) # * 75% – верхний квартиль (значение, которое 75% значений не превышают) # Подробнее о полученной таблице поговорим в следующий раз.