Python для сбора данных

Алла Тамбовцева, НИУ ВШЭ

Семинар 5 по теме: группировка и агрегирование

Часть 1: загрузка и преобразование файла JSON

В рамках этого семинара мы поработаем с файлом в формате JSON.

JSON расшифровывается как JavaScript Object Notation. Изначально этот формат хранения данных использовался в языке JavaScript, но теперь он потерял привязку к конкретному языку программирования и стал универсальным. С форматом JSON можно столкнуться при обращении к API, базам данных; формат часто применяется для хранения информации на сервере, к которому обращается сайт, например, в зависимости от запросов пользователей. Object здесь можно понимать как некоторую структуру хранения данных (список, кортеж, словарь), которая записывается в специальном виде, внешне напоминающим обычную строку.

Импортируем модуль json:

In [31]:
import json

Начнём работать с реальными данными. Зайдём на Портал открытых данных Правительства Москвы в раздел Образование и выберем набор данных Победители олимпиад. Кликнем Экспорт и скачаем файл в формате json. Скачается, правда, zip-архив, но его можно распаковать. Сохраним название файла (или путь к нему) в переменную name:

In [2]:
name = "data-27257-2020-02-03.json"

Теперь загрузим содержимое файла в Python. Вообще при работе с json-файлами выделяют две операции: десериализация и сериализация. Десериализация – это преобразование объекта JSON в другую структуру данных (например, в питоновский словарь или список), а сериализация – это запись данных в формат JSON. Десериализуем:

In [3]:
with open(name, "r", encoding="Windows-1251") as read_file:
    data = json.load(read_file)

Запись с with open() as read_file эквивалентна созданию переменной read_file и присваиванию ей значения из open(). Плюс, так как текст в файле на кириллице, при загрузке файла имеет смысл указать кодировку (здесь это Windows-1251), иначе файл может не открыться или открыться, но с крокозябрами вместо букв.

Посмотрим на data:

In [ ]:
data

В переменной data сохранён список словарей. Можем посмотреть на первый элемент списка:

In [5]:
data[0]
Out[5]:
{'global_id': 4472939,
 'Year': '2012/2013',
 'ShortName': 'ГБОУ лицей «Вторая школа»',
 'OlympiadType': 'Всероссийская олимпиада',
 'Stage': '3',
 'Class': '11',
 'Subject': 'Иностранный язык (английский язык)',
 'Status': 'призёр',
 'FullName': 'Государственное бюджетное общеобразовательное учреждение города Москвы «Лицей «Вторая школа»'}

Если привести данные в таком формате к привычному табличному виду, то получится, что в таблице у нас есть 9 столбцов (с global_id по FullName), а каждая строка таблицы описывается словарём как в ячейке выше. Данные в таком формате удобно хранить, к ним удобно писать запросы, выбирая значения по ключам в словарях, но иногда логичнее поместить их в таблицу. Для этого нам понадобится библиотека pandas:

In [ ]:
import pandas as pd

Превратим список словарей data в таблицу (датафрейм pandas):

In [6]:
olymp = pd.DataFrame(data)

Посмотрим на первые несколько строк:

In [32]:
olymp.head() 
Out[32]:
global_id Year ShortName OlympiadType Stage Class Subject Status FullName
0 4472939 2012/2013 ГБОУ лицей «Вторая школа» Всероссийская олимпиада 3 11 Иностранный язык (английский язык) призёр Государственное бюджетное общеобразовательное ...
1 4472940 2012/2013 ГБОУ лицей «Вторая школа» Всероссийская олимпиада 3 11 Иностранный язык (английский язык) призёр Государственное бюджетное общеобразовательное ...
2 4472941 2012/2013 ГБОУ лицей «Вторая школа» Всероссийская олимпиада 3 10 Иностранный язык (английский язык) призёр Государственное бюджетное общеобразовательное ...
3 4472942 2012/2013 ГБОУ СОШ № 26 Всероссийская олимпиада 4 11 Иностранный язык (английский язык) победитель Государственное бюджетное образовательное учре...
4 4472943 2012/2013 ГБОУ СОШ № 26 Всероссийская олимпиада 3 11 Иностранный язык (английский язык) призёр Государственное бюджетное образовательное учре...

Часть 2: группировка и агрегирование

Все задания выполняются на основе датафрейма olymp, полученного в предыдущей части.

Задание 1

Приведите столбец Class к целочисленному типу.

Задание 2

Выведите уникальные значения в столбце OlympiadType.

Задание 3

Сгруппируйте строки в соответствии со значениями в столбце OlympiadType и сохраните в отдельные csv-файл данные по Всероссийской олимпиаде и по Московской олимпиаде. Файлы должны называться Всероссийская олимпиада.csv и Московская олимпиада.csv.

Задание 4

Выведите таблицу с числом участников олимпиад с группировкой по типу олимпиады и статусу участника. Сохраните полученный результат в переменную res.

Задание 5

a) Используя результат в переменной res, выведите на экран число победителей и призеров только Всероссийской олимпиады.

b) Используя результат в переменной res, выведите на экран число победителей и призеров только Московской олимпиады.

c) Используя результат в переменной res, выведите на экран число победителей Всероссийской олимпиады. Это должно быть одно число.

Задание 6

Выведите медианное значение класса для каждого типа олимпиады и статуса участника, используя группировку и метод для агрегирования. Сохраните результат в переменную res2. Удалите в res2 столбец global_id, переименуйте столбец Class в Класс (медиана).

Задание 7

Получите код HTML для объекта res2, используя метод .to_html(). Скопируйте полученный код сюда, поместив его между тэгами <body> и </body>, кликните Run. Порефлексируйте над полученным результатом – знание устройства html-файлов очень поможет потом при парсинге файлов из интернета.