{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Программирование на Python\n", "\n", "*Алла Тамбовцева, НИУ ВШЭ*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### JSON-файлы и таблицы `pandas`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "JSON расшифровывается как *JavaScript Object Notation*. Изначально этот формат хранения данных использовался в языке JavaScript, но теперь он потерял привязку к конкретному языку программирования и стал универсальным. С форматом JSON можно столкнуться при обращении к API, базам данных; формат часто применяется для хранения информации на сервере, к которому обращается сайт, например, в зависимости от запросов пользователей. *Object* здесь можно понимать как некоторую структуру хранения данных (список, кортеж, словарь), которая записывается в специальном виде, внешне напоминающим обычную строку. \n", "\n", "Импортируем модуль `json`:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "import json" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Начнём работать с реальными данными. Зайдём на [Портал](https://data.mos.ru/) открытых данных Правительства Москвы в раздел *Образование* и выберем набор данных *Перечень олимпиад школьников*. Кликнем *Экспорт* и скачаем файл в формате json. Скачается, правда, zip-архив, но его можно распаковать. Сохраним полный путь к json-файлу в переменную `name`:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "name = '/Users/allat/Desktop/data-6114-2018-12-10.json'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Теперь загрузим содержимое файла в Python. Вообще при работе с json-файлами выделяют две операции: *десериализация* и *сериализация*. Десериализация – это преобразование объекта JSON в другую структуру данных (например, в питоновский словарь или список), а сериализация – это запись данных в формат JSON. Десериализуем: " ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "with open(name, \"r\", encoding=\"Windows-1251\") as read_file:\n", " data = json.load(read_file)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Запись с `with open() as read_file` эквивалентна созданию переменной `read_file` и присваиванию ей значения из `open()`. Плюс, так как текст в файле на кириллице, при загрузке файла имеет смысл указать кодировку (здесь это *Windows-1251*), иначе файл может не открыться или открыться, но с крокозябрами вместо букв.\n", "\n", "Посмотрим на `data`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В переменной `data` сохранён список словарей. Можем посмотреть на первый элемент списка:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'global_id': 39706536,\n", " 'ID': 43,\n", " 'Name': 'Всероссийская олимпиада по технологии',\n", " 'WebSite': [{'WebSite': 'vos.olimpiada.ru/2015/okrug'}],\n", " 'OlympiadType': 'Всероссийская олимпиада',\n", " 'Class': '7 - 11',\n", " 'Stage': 2,\n", " 'OlympiadDate': '05.12.2015',\n", " 'SchoolYear': 2015,\n", " 'Theme': 'Технология'}" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если привести данные в таком формате к привычному табличному виду, то получится, что в таблице у нас есть 8 столбцов (с *global_id* по *AdmArea*), а каждая строка таблицы описывается словарём как в ячейке выше. Данные в таком формате удобно хранить, к ним удобно писать запросы, выбирая значения по ключам в словарях, но иногда логичнее поместить их в таблицу. Для этого нам понадобится библиотека `pandas`:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Превратим список словарей `data` в таблицу (датафрейм *pandas*):" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "df = pd.DataFrame(data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Посмотрим на неё:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | Class | \n", "ID | \n", "Name | \n", "OlympiadDate | \n", "OlympiadType | \n", "SchoolYear | \n", "Stage | \n", "Theme | \n", "WebSite | \n", "global_id | \n", "
---|---|---|---|---|---|---|---|---|---|---|
0 | \n", "7 - 11 | \n", "43 | \n", "Всероссийская олимпиада по технологии | \n", "05.12.2015 | \n", "Всероссийская олимпиада | \n", "2015 | \n", "2.0 | \n", "Технология | \n", "[{'WebSite': 'vos.olimpiada.ru/2015/okrug'}] | \n", "39706536 | \n", "
1 | \n", "9 - 11 | \n", "44 | \n", "Всероссийская олимпиада по технологии | \n", "01.02.2016, 02.02.2016 | \n", "Всероссийская олимпиада | \n", "2016 | \n", "3.0 | \n", "Технология | \n", "[{'WebSite': 'vos.olimpiada.ru/2016/region'}] | \n", "39706537 | \n", "
2 | \n", "6 - 7 | \n", "45 | \n", "Математический праздник | \n", "21.02.2016 | \n", "Московская олимпиада | \n", "2016 | \n", "NaN | \n", "Математика | \n", "[{'WebSite': 'olympiads.mccme.ru/matprazdnik/'}] | \n", "39706538 | \n", "
3 | \n", "5 - 11 | \n", "46 | \n", "Московская астрономическая олимпиада | \n", "06.02.2016 | \n", "Московская олимпиада | \n", "2016 | \n", "NaN | \n", "Астрономия | \n", "[{'WebSite': 'astroolymp.ru/'}] | \n", "39706540 | \n", "
4 | \n", "5 - 11 | \n", "47 | \n", "Московская астрономическая олимпиада | \n", "09.12.2015 - 18.01.2016 | \n", "Московская олимпиада | \n", "2016 | \n", "NaN | \n", "Астрономия | \n", "[{'WebSite': 'astroolymp.ru/'}] | \n", "39706541 | \n", "