{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Класс для объединения множества однотипных файлов excel в один набор данных\n",
"----------\n",
"\n",
"Постановка задачи (что наш класс должен уметь):\n",
" - собирать файлы:\n",
" - из файловой системы по маске;\n",
" - с веб-сервера (может быть даже с предварительной авторизацией);\n",
" - скачивать и доставать книги из архивов, в т.ч. если в архиве много однотипных файлов;\n",
" - объединять таблицы с данными:\n",
" - из определённых листов загружаемых книг (например первый лист каждой книги)\n",
" - перебирая все рабочие листы всех загружаемых книг\n",
" - добавлять в итоговый набор произвольное количество колонок, идентифицирующих источник:\n",
" - название файла;\n",
" - название рабочего листа;\n",
" - произвольные ячейки каждого рабочего листа, например заголовок или подпись ответственного лица, даты и т.д.\n",
" - выводить получаемый набор в выбранном формате:\n",
" - DataFrame;\n",
" - генератор словарей;\n",
" - генератор NamedTyple;\n",
" - записывать в csv или базу данных."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Установка и импорт зависимостей"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: pandas in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (1.0.1)\n",
"Requirement already satisfied: openpyxl in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (3.0.3)\n",
"Requirement already satisfied: xlrd in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (1.2.0)\n",
"Requirement already satisfied: chardet in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (3.0.4)\n",
"Requirement already satisfied: numpy>=1.13.3 in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from pandas) (1.18.1)\n",
"Requirement already satisfied: pytz>=2017.2 in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from pandas) (2019.3)\n",
"Requirement already satisfied: python-dateutil>=2.6.1 in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from pandas) (2.8.1)\n",
"Requirement already satisfied: jdcal in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from openpyxl) (1.4.1)\n",
"Requirement already satisfied: et_xmlfile in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from openpyxl) (1.0.1)\n",
"Requirement already satisfied: six>=1.5 in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from python-dateutil>=2.6.1->pandas) (1.14.0)\n"
]
}
],
"source": [
"!pip install pandas openpyxl xlrd chardet"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import sys\n",
"import glob\n",
"import re\n",
"from itertools import islice\n",
"from collections.abc import Iterable\n",
"from urllib.parse import urlparse\n",
"from urllib.request import urlopen\n",
"\n",
"import pandas as pd\n",
"import openpyxl"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Объявление класса"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"class ExcelPreprocessor:\n",
" def __init__(self, *wb, append_global_index=False, append_wb_index=False, \n",
" filename_parser=None, append_ws_title_column=False, first_row_number=1,\n",
" iterate_over_worksheet=0, cells=None, headers=None):\n",
" '''\n",
" параметр iterate_over_worksheet отвечает за то, какой именно рабочий лист в каждой прочитанной\n",
" книге будет разобран по умолчанию это лист с индексом 0, т.е. 1 в списке.\n",
" Номера листов можно задать списком, например [4, 5] (пятый и шестой соответственно)\n",
" также можно указать \"ALL\" или True, тогда будут прочитаны все листы всех книг\n",
" и данные из них объединены в один набор\n",
" '''\n",
" self.wb = []\n",
" for w in wb:\n",
" if isinstance(w, list):\n",
" self.wb += w\n",
" elif isinstance(w, str):\n",
" self.wb += [w]\n",
" else:\n",
" raise Exception(f'the \"{w}\" is of type {type(w)}, need list or str')\n",
"\n",
" self.global_index = append_global_index\n",
" self.wb_index = append_wb_index\n",
" self.filename_parser = filename_parser\n",
" self.append_ws_title_column = append_ws_title_column\n",
" self.first_row_number = first_row_number\n",
" self.iterate_over_worksheet = iterate_over_worksheet\n",
" self.cells = cells\n",
" self.headers = headers\n",
"\n",
" def __repr__(self):\n",
" return f'''{ExcelPreprocessor.__name__}{self.wb}:\n",
" add global index: {self.global_index}\n",
" add workbook index: {self.wb_index}\n",
" filename parser: {self.filename_parser}\n",
" append worksheet title: {self.append_ws_title_column}\n",
" first row number in worksheet: {self.first_row_number}\n",
" worksheets in all wb to iterate: {self.iterate_over_worksheet}\n",
" cells: {self.cells}\n",
" headers: {self.headers}'''\n",
"\n",
" @property\n",
" def _process_files(self):\n",
" '''\n",
" обрабатывает файлы в списке\n",
" принимает обычные файлы, zip-архивы и http - пути\n",
" '''\n",
" for filename in self.wb:\n",
" rf = filename\n",
" if filename.startswith('http'):\n",
" import io\n",
" with urlopen(filename) as resp:\n",
" rf = io.BytesIO(resp.read())\n",
" if filename.endswith('.xlsx'):\n",
" yield filename, rf\n",
" elif filename.endswith('xlsx'):\n",
" yield filename, open(filename, 'rb')\n",
"\n",
" if filename.endswith('.zip'):\n",
" from zipfile import ZipFile\n",
" import chardet\n",
" ZIP_FILENAME_UTF8_FLAG = 0x800\n",
" zf = ZipFile(rf , 'r')\n",
" for info in zf.filelist:\n",
" filename = info.filename\n",
" if info.flag_bits & ZIP_FILENAME_UTF8_FLAG == 0:\n",
" filename_bytes = filename.encode('437')\n",
" guessed_encoding = chardet.detect(filename_bytes)['encoding'] or 'cp1252'\n",
" filename = filename_bytes.decode(guessed_encoding, 'replace')\n",
" yield filename, zf.open(info.filename, 'r')\n",
"\n",
" @property\n",
" def _columns(self):\n",
" columns = []\n",
" if self.global_index:\n",
" columns.append('global_index')\n",
" if self.wb_index:\n",
" columns.append('ws_index')\n",
" if self.filename_parser:\n",
" columns += self.filename_parser(self.wb[0]).keys()\n",
" if self.append_ws_title_column:\n",
" columns.append('ws_title')\n",
" if self.cells:\n",
" columns += self.cells.keys()\n",
" if self.headers:\n",
" columns += self.headers\n",
" return columns\n",
"\n",
" def _iter_over_rows(self):\n",
" 'итерация по общей последовательности строк в итоговом наборе'\n",
" \n",
" row_counter = 0\n",
"\n",
" for fn, excel_file in self._process_files:\n",
" wb = openpyxl.load_workbook(excel_file, read_only=True, data_only=False, keep_links=False)\n",
"\n",
" if isinstance(self.iterate_over_worksheet, int):\n",
" iter_sheet = [self.iterate_over_worksheet]\n",
" elif isinstance(self.iterate_over_worksheet, Iterable):\n",
" iter_sheet = self.iterate_over_worksheet\n",
" else:\n",
" iter_sheet = [i for i, ws in enumerate(ws.worksheets)]\n",
"\n",
" for ws_index in iter_sheet:\n",
" ws = wb.worksheets[ws_index]\n",
" result = ((cell.value for cell in row) for row in ws.rows)\n",
"\n",
" if self.first_row_number:\n",
" result = islice(result, self.first_row_number - 1, None)\n",
" if self.cells:\n",
" retry_cols_values = [ws[c].value for c in self.cells.values()]\n",
" result = ((*retry_cols_values, *row) for row in result)\n",
" if self.append_ws_title_column:\n",
" result = ((ws.title, *row) for row in result)\n",
" if self.filename_parser:\n",
" fncols = self.filename_parser(fn)\n",
" result = ((*fncols.values(), *row) for row in result)\n",
" if self.wb_index:\n",
" result = ((i, *row) for i, row in enumerate(result))\n",
" if self.global_index:\n",
" result = ((row_counter, *row) for i, row in enumerate(result))\n",
" for row in result:\n",
" yield row\n",
" row_counter += 1\n",
"\n",
" def get_dataframe(self):\n",
" 'возвращает набор данных в виде pandas DataFrame'\n",
" return pd.DataFrame({'hello': []})\n",
"\n",
" def write_csv(self, csv_filename):\n",
" 'записывает набор данных в файл csv'\n",
" return None\n",
"\n",
" def write_excel(excel_filename):\n",
" 'записывает набор данных в файл excel'\n",
" return None\n",
"\n",
" def get_iter_dict(self):\n",
" 'возвращает набор данных в виде итератора словарей'\n",
" cols = self._columns\n",
" for row in self._iter_over_rows():\n",
" yield {k:v for k, v in zip(cols, row)}\n",
"\n",
" def get_iter_nt(self):\n",
" 'возвращает набор данных в виде итерируемого набора NamedTyple'\n",
" from collections import namedtuple\n",
" cols = self._columns\n",
" nt = namedtuple(\"Row\", [c.replace(' ', '_').replace('.', '_').replace('(', '_').replace(')', '_') for c in cols])\n",
" for row in self._iter_over_rows():\n",
" yield nt(*row)\n",
"\n",
" def get_sample(self, start, stop):\n",
" 'возвращает сэмпл итогового набора (можно проверить правильность обработки данных)'\n",
" return [list(row) for row in islice(self._iter_over_rows(), start, stop)]"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"ExcelPreprocessor['data\\\\2009\\\\4nm010618.xlsx', 'data\\\\2008\\\\4nm011118.xlsx']:\n",
" add global index: False\n",
" add workbook index: False\n",
" filename parser: None\n",
" append worksheet title: False\n",
" first row number in worksheet: 1\n",
" worksheets in all wb to iterate: 0\n",
" cells: None\n",
" headers: None"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# создаем экземпляр класса и смотрим что получается\n",
"processor = ExcelPreprocessor('data\\\\2009\\\\4nm010618.xlsx', 'data\\\\2008\\\\4nm011118.xlsx')\n",
"processor"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[None, 'Код стро-ки', 'Всего ', 'из графы 1 по :', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n",
"[None, None, None, 'федеральным налогам и сборам', None, None, None, None, None, None, None, 'региональным налогам и сборам', 'местным налогам и сборам', 'налогам со специальным налоговым режимом', 'Единому социальному налогу', 'Из графы 13 единый социальный налог в федеральный бюджет', 'Платежам в государственные внебюджетные фонды', 'ВСЕГО задолженность по страховым взносам', None, None, None, None, None, None]\n",
"[None, None, None, 'Всего ', 'из них', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n",
"[None, None, None, None, 'налог на прибыль организаций', None, 'налог на добавленную стоимость ', 'из графы 5 налог на добавленную стоимость по товарам (работам, услугам), реализуемым на территории РФ', 'платежи за пользование природными ресурсами ', 'из графы 7\\n налог на добычу полезных ископаемых', 'остальные федеральные налоги и сборы', None, None, None, None, None, None, None, None, None, None, None, None, None]\n",
"[None, None, None, None, 'Всего ', 'в том числе в федеральный бюджет', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n",
"['А', 'Б', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, None, None, None, None, None, None]\n"
]
}
],
"source": [
"# попробуем получить кусочек данных например с 5 по 8 строку и посмотреть что получается\n",
"for row in processor.get_sample(5, 11):\n",
" print(row)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1093)', 1005, 1235462116, 613079956, 137068882, 16509931, 378521695, 377407864, 7475610, 7001696, 90013769, 152239095, 76851905, 52246651, 4059156, 2911250, 892339, 336093014, None, None, None, None, None, None]\n",
"['Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРАМ, ПЕНЯМ, НАЛОГОВЫМ САНКЦИЯМ ВСЕГО В ТОМ ЧИСЛЕ:', 1010, 966783423, 470685208, 102647180, 12435295, 293731518, 292643494, 6239798, 6015450, 68066712, 122048711, 66194027, 50606745, 2990596, 2027362, 838342, 253419794, None, None, None, None, None, None]\n",
"['Уточненные данные по состоянию на 16.07.2018\\n', 'из нее\\nзадолженность, невозможная к взысканию в связи с отложением подачи заявления в арбитражный суд о признании должника банкротом', 1011, 59789575, 45827009, 6993023, 772092, 33088224, 32865309, 70488, 41193, 5675274, 369196, 357281, 3524787, 92613, 75241, 41612, 9577077, None, None, None, None, None, None]\n",
"['Уточненные данные по состоянию на 16.07.2018\\n', 'НЕДОИМКА', 1020, 738863445, 350780985, 76405303, 9214666, 221615329, 220703752, 5920609, 5756088, 46839744, 98789604, 54482333, 37990418, 896167, 605705, 190163, 195733775, None, None, None, None, None, None]\n"
]
}
],
"source": [
"# Видим что данные начинаются только с 12 строки, к тому же нам надо добавить\n",
"# в каждую строку информацию из ячейки \"A1\", назовём её \"date_ot\"\n",
"processor.cells = {'date_ot': 'A1'}\n",
"processor.first_row_number = 12\n",
"for row in processor.get_sample(0, 4):\n",
" print(row)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['2009', '4nm010618', 'xlsx', 'Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1093)', 1005, 1235462116, 613079956, 137068882, 16509931, 378521695, 377407864, 7475610, 7001696, 90013769, 152239095, 76851905, 52246651, 4059156, 2911250, 892339, 336093014, None, None, None, None, None, None]\n",
"['2009', '4nm010618', 'xlsx', 'Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРАМ, ПЕНЯМ, НАЛОГОВЫМ САНКЦИЯМ ВСЕГО В ТОМ ЧИСЛЕ:', 1010, 966783423, 470685208, 102647180, 12435295, 293731518, 292643494, 6239798, 6015450, 68066712, 122048711, 66194027, 50606745, 2990596, 2027362, 838342, 253419794, None, None, None, None, None, None]\n",
"['2009', '4nm010618', 'xlsx', 'Уточненные данные по состоянию на 16.07.2018\\n', 'из нее\\nзадолженность, невозможная к взысканию в связи с отложением подачи заявления в арбитражный суд о признании должника банкротом', 1011, 59789575, 45827009, 6993023, 772092, 33088224, 32865309, 70488, 41193, 5675274, 369196, 357281, 3524787, 92613, 75241, 41612, 9577077, None, None, None, None, None, None]\n",
"['2009', '4nm010618', 'xlsx', 'Уточненные данные по состоянию на 16.07.2018\\n', 'НЕДОИМКА', 1020, 738863445, 350780985, 76405303, 9214666, 221615329, 220703752, 5920609, 5756088, 46839744, 98789604, 54482333, 37990418, 896167, 605705, 190163, 195733775, None, None, None, None, None, None]\n"
]
}
],
"source": [
"# добавим функцию для того чтобы извлечь из имён файлов полезную информацию и потом добавить её в наш набор данных\n",
"# один файл выглядит так: 'data\\\\2009\\\\4nm010618.xlsx'\n",
"# сделаем функцию, которая принимает название файла в таком формате и регулярным выражением возвращает год, название файла и его расширение\n",
"\n",
"def parse_filename(filename):\n",
" rstring = r'data\\\\(?P<year>\\w+)\\\\(?P<filename>\\w+)\\.(?P<extension>\\w+)'\n",
" r = re.match(rstring, filename)\n",
" return r.groupdict()\n",
"\n",
"processor.filename_parser = parse_filename\n",
"for row in processor.get_sample(0, 4):\n",
" print(row)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0, 0, '2009', '4nm010618', 'xlsx', 'P1', 'Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1093)', 1005, 1235462116, 613079956, 137068882, 16509931, 378521695, 377407864, 7475610, 7001696, 90013769, 152239095, 76851905, 52246651, 4059156, 2911250, 892339, 336093014, None, None, None, None, None, None]\n",
"[1, 1, '2009', '4nm010618', 'xlsx', 'P1', 'Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРАМ, ПЕНЯМ, НАЛОГОВЫМ САНКЦИЯМ ВСЕГО В ТОМ ЧИСЛЕ:', 1010, 966783423, 470685208, 102647180, 12435295, 293731518, 292643494, 6239798, 6015450, 68066712, 122048711, 66194027, 50606745, 2990596, 2027362, 838342, 253419794, None, None, None, None, None, None]\n",
"[2, 2, '2009', '4nm010618', 'xlsx', 'P1', 'Уточненные данные по состоянию на 16.07.2018\\n', 'из нее\\nзадолженность, невозможная к взысканию в связи с отложением подачи заявления в арбитражный суд о признании должника банкротом', 1011, 59789575, 45827009, 6993023, 772092, 33088224, 32865309, 70488, 41193, 5675274, 369196, 357281, 3524787, 92613, 75241, 41612, 9577077, None, None, None, None, None, None]\n",
"[3, 3, '2009', '4nm010618', 'xlsx', 'P1', 'Уточненные данные по состоянию на 16.07.2018\\n', 'НЕДОИМКА', 1020, 738863445, 350780985, 76405303, 9214666, 221615329, 220703752, 5920609, 5756088, 46839744, 98789604, 54482333, 37990418, 896167, 605705, 190163, 195733775, None, None, None, None, None, None]\n"
]
}
],
"source": [
"# теперь добавим в наш результируюший набор поле сквозного индекса\n",
"# и отдельный индекс по каждому рабочему листу, что нам попадётся\n",
"processor.global_index = True\n",
"processor.wb_index = True\n",
"# также нелишним будет добавить и колонку с заголовком рабочего листа с которого получены данные\n",
"processor.append_ws_title_column = True\n",
"for row in processor.get_sample(0, 4):\n",
" print(row)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'global_index': 0, 'ws_index': 0, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n'}\n",
"{'global_index': 1, 'ws_index': 1, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n'}\n",
"{'global_index': 2, 'ws_index': 2, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n'}\n",
"{'global_index': 3, 'ws_index': 3, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n'}\n",
"{'global_index': 4, 'ws_index': 4, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n'}\n"
]
}
],
"source": [
"# посмотрим то же самое в формате набора словарей:\n",
"for row in islice(processor.get_iter_dict(), 0, 5):\n",
" print(row)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'global_index': 0, 'ws_index': 0, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n', 'поле': 'ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1093)', 'код строки': 1005, 'кол. налогоплательщиков': 1235462116, 'всего': 613079956, 'по налогу (сбору)': 137068882, 'по пени': 16509931, 'по штрафам': 378521695, 'проценты': 377407864, 'по ЕСН': 7475610, 'по страховым взносам': 7001696}\n",
"{'global_index': 1, 'ws_index': 1, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n', 'поле': 'ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРАМ, ПЕНЯМ, НАЛОГОВЫМ САНКЦИЯМ ВСЕГО В ТОМ ЧИСЛЕ:', 'код строки': 1010, 'кол. налогоплательщиков': 966783423, 'всего': 470685208, 'по налогу (сбору)': 102647180, 'по пени': 12435295, 'по штрафам': 293731518, 'проценты': 292643494, 'по ЕСН': 6239798, 'по страховым взносам': 6015450}\n",
"{'global_index': 2, 'ws_index': 2, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n', 'поле': 'из нее\\nзадолженность, невозможная к взысканию в связи с отложением подачи заявления в арбитражный суд о признании должника банкротом', 'код строки': 1011, 'кол. налогоплательщиков': 59789575, 'всего': 45827009, 'по налогу (сбору)': 6993023, 'по пени': 772092, 'по штрафам': 33088224, 'проценты': 32865309, 'по ЕСН': 70488, 'по страховым взносам': 41193}\n",
"{'global_index': 3, 'ws_index': 3, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n', 'поле': 'НЕДОИМКА', 'код строки': 1020, 'кол. налогоплательщиков': 738863445, 'всего': 350780985, 'по налогу (сбору)': 76405303, 'по пени': 9214666, 'по штрафам': 221615329, 'проценты': 220703752, 'по ЕСН': 5920609, 'по страховым взносам': 5756088}\n",
"{'global_index': 4, 'ws_index': 4, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n', 'поле': '\\nИз строки 1020\\nНЕДОИМКА ОРГАНИЗАЦИЙ И ИНДИВИДУАЛЬНЫХ ПРЕДПРИНИМАТЕЛЕЙ, НЕ ПРЕДСТАВЛЯЮЩИХ ОТЧЕТНОСТЬ', 'код строки': 1030, 'кол. налогоплательщиков': 105337216, 'всего': 68231581, 'по налогу (сбору)': 16344932, 'по пени': 1759494, 'по штрафам': 47161217, 'проценты': 47056987, 'по ЕСН': 36418, 'по страховым взносам': 27229}\n"
]
}
],
"source": [
"# видно что не хватает колонок, т.к. не задан параметр \"headers\". исправим это\n",
"processor.headers = [\n",
" 'поле', 'код строки', 'кол. налогоплательщиков', 'всего', 'по налогу (сбору)',\n",
" 'по пени', 'по штрафам', 'проценты', 'по ЕСН', 'по страховым взносам'\n",
"]\n",
"for row in islice(processor.get_iter_dict(), 0, 5):\n",
" print(row)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>global_index</th>\n",
" <th>ws_index</th>\n",
" <th>year</th>\n",
" <th>filename</th>\n",
" <th>extension</th>\n",
" <th>ws_title</th>\n",
" <th>date_ot</th>\n",
" <th>поле</th>\n",
" <th>код строки</th>\n",
" <th>кол. налогоплательщиков</th>\n",
" <th>всего</th>\n",
" <th>по налогу (сбору)</th>\n",
" <th>по пени</th>\n",
" <th>по штрафам</th>\n",
" <th>проценты</th>\n",
" <th>по ЕСН</th>\n",
" <th>по страховым взносам</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>P1</td>\n",
" <td>Уточненные данные по состоянию на 16.07.2018\\n</td>\n",
" <td>ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1...</td>\n",
" <td>1005.0</td>\n",
" <td>1.235462e+09</td>\n",
" <td>613079956.0</td>\n",
" <td>137068882.0</td>\n",
" <td>16509931.0</td>\n",
" <td>378521695.0</td>\n",
" <td>377407864.0</td>\n",
" <td>7475610.0</td>\n",
" <td>7001696.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>P1</td>\n",
" <td>Уточненные данные по состоянию на 16.07.2018\\n</td>\n",
" <td>ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРА...</td>\n",
" <td>1010.0</td>\n",
" <td>9.667834e+08</td>\n",
" <td>470685208.0</td>\n",
" <td>102647180.0</td>\n",
" <td>12435295.0</td>\n",
" <td>293731518.0</td>\n",
" <td>292643494.0</td>\n",
" <td>6239798.0</td>\n",
" <td>6015450.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>P1</td>\n",
" <td>Уточненные данные по состоянию на 16.07.2018\\n</td>\n",
" <td>из нее\\nзадолженность, невозможная к взысканию...</td>\n",
" <td>1011.0</td>\n",
" <td>5.978958e+07</td>\n",
" <td>45827009.0</td>\n",
" <td>6993023.0</td>\n",
" <td>772092.0</td>\n",
" <td>33088224.0</td>\n",
" <td>32865309.0</td>\n",
" <td>70488.0</td>\n",
" <td>41193.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>P1</td>\n",
" <td>Уточненные данные по состоянию на 16.07.2018\\n</td>\n",
" <td>НЕДОИМКА</td>\n",
" <td>1020.0</td>\n",
" <td>7.388634e+08</td>\n",
" <td>350780985.0</td>\n",
" <td>76405303.0</td>\n",
" <td>9214666.0</td>\n",
" <td>221615329.0</td>\n",
" <td>220703752.0</td>\n",
" <td>5920609.0</td>\n",
" <td>5756088.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>P1</td>\n",
" <td>Уточненные данные по состоянию на 16.07.2018\\n</td>\n",
" <td>\\nИз строки 1020\\nНЕДОИМКА ОРГАНИЗАЦИЙ И ИНДИВ...</td>\n",
" <td>1030.0</td>\n",
" <td>1.053372e+08</td>\n",
" <td>68231581.0</td>\n",
" <td>16344932.0</td>\n",
" <td>1759494.0</td>\n",
" <td>47161217.0</td>\n",
" <td>47056987.0</td>\n",
" <td>36418.0</td>\n",
" <td>27229.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" global_index ws_index year filename extension ws_title \\\n",
"0 0 0 2009 4nm010618 xlsx P1 \n",
"1 1 1 2009 4nm010618 xlsx P1 \n",
"2 2 2 2009 4nm010618 xlsx P1 \n",
"3 3 3 2009 4nm010618 xlsx P1 \n",
"4 4 4 2009 4nm010618 xlsx P1 \n",
"\n",
" date_ot \\\n",
"0 Уточненные данные по состоянию на 16.07.2018\\n \n",
"1 Уточненные данные по состоянию на 16.07.2018\\n \n",
"2 Уточненные данные по состоянию на 16.07.2018\\n \n",
"3 Уточненные данные по состоянию на 16.07.2018\\n \n",
"4 Уточненные данные по состоянию на 16.07.2018\\n \n",
"\n",
" поле код строки \\\n",
"0 ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1... 1005.0 \n",
"1 ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРА... 1010.0 \n",
"2 из нее\\nзадолженность, невозможная к взысканию... 1011.0 \n",
"3 НЕДОИМКА 1020.0 \n",
"4 \\nИз строки 1020\\nНЕДОИМКА ОРГАНИЗАЦИЙ И ИНДИВ... 1030.0 \n",
"\n",
" кол. налогоплательщиков всего по налогу (сбору) по пени \\\n",
"0 1.235462e+09 613079956.0 137068882.0 16509931.0 \n",
"1 9.667834e+08 470685208.0 102647180.0 12435295.0 \n",
"2 5.978958e+07 45827009.0 6993023.0 772092.0 \n",
"3 7.388634e+08 350780985.0 76405303.0 9214666.0 \n",
"4 1.053372e+08 68231581.0 16344932.0 1759494.0 \n",
"\n",
" по штрафам проценты по ЕСН по страховым взносам \n",
"0 378521695.0 377407864.0 7475610.0 7001696.0 \n",
"1 293731518.0 292643494.0 6239798.0 6015450.0 \n",
"2 33088224.0 32865309.0 70488.0 41193.0 \n",
"3 221615329.0 220703752.0 5920609.0 5756088.0 \n",
"4 47161217.0 47056987.0 36418.0 27229.0 "
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# попробуем то же самое в виде DataFrame\n",
"pd.DataFrame(processor.get_iter_dict())[:5]"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>global_index</th>\n",
" <th>ws_index</th>\n",
" <th>year</th>\n",
" <th>filename</th>\n",
" <th>extension</th>\n",
" <th>ws_title</th>\n",
" <th>form_name</th>\n",
" <th>description</th>\n",
" <th>form_dt</th>\n",
" <th>unit_name</th>\n",
" <th>поле</th>\n",
" <th>код строки</th>\n",
" <th>кол. налогоплательщиков</th>\n",
" <th>всего</th>\n",
" <th>по налогу (сбору)</th>\n",
" <th>по пени</th>\n",
" <th>по штрафам</th>\n",
" <th>проценты</th>\n",
" <th>по ЕСН</th>\n",
" <th>по страховым взносам</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.06.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности организаций, лик...</td>\n",
" <td>2400</td>\n",
" <td>23632</td>\n",
" <td>30705385</td>\n",
" <td>18388429</td>\n",
" <td>4699527</td>\n",
" <td>1439452</td>\n",
" <td>184237</td>\n",
" <td>596724</td>\n",
" <td>5397016</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.06.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности индивидуальных п...</td>\n",
" <td>2405</td>\n",
" <td>9109</td>\n",
" <td>3013574</td>\n",
" <td>1661920</td>\n",
" <td>881213</td>\n",
" <td>242978</td>\n",
" <td>628</td>\n",
" <td>51928</td>\n",
" <td>174907</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.06.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности умерших или объя...</td>\n",
" <td>2410</td>\n",
" <td>39920</td>\n",
" <td>677495</td>\n",
" <td>115346</td>\n",
" <td>44047</td>\n",
" <td>11984</td>\n",
" <td>0</td>\n",
" <td>5203</td>\n",
" <td>500915</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.06.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности в случаях принят...</td>\n",
" <td>2415</td>\n",
" <td>58635</td>\n",
" <td>2161183</td>\n",
" <td>773472</td>\n",
" <td>556271</td>\n",
" <td>70216</td>\n",
" <td>5769</td>\n",
" <td>154600</td>\n",
" <td>600855</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.06.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности по \"зависшим\" пл...</td>\n",
" <td>2420</td>\n",
" <td>93</td>\n",
" <td>43115</td>\n",
" <td>31946</td>\n",
" <td>752</td>\n",
" <td>76</td>\n",
" <td>0</td>\n",
" <td>5527</td>\n",
" <td>4814</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>5</td>\n",
" <td>5</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.06.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности организаций, отв...</td>\n",
" <td>2425</td>\n",
" <td>25104</td>\n",
" <td>4038755</td>\n",
" <td>2487632</td>\n",
" <td>1003525</td>\n",
" <td>215253</td>\n",
" <td>х</td>\n",
" <td>29516</td>\n",
" <td>302829</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>6</td>\n",
" <td>6</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.06.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности по решениям нало...</td>\n",
" <td>2430</td>\n",
" <td>16841363</td>\n",
" <td>60557919</td>\n",
" <td>41458668</td>\n",
" <td>19050086</td>\n",
" <td>325</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>48839</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>7</td>\n",
" <td>7</td>\n",
" <td>2009</td>\n",
" <td>4nm010618</td>\n",
" <td>xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.06.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма задолженности, списанной на основании з...</td>\n",
" <td>2435</td>\n",
" <td>1799585</td>\n",
" <td>133435115</td>\n",
" <td>36498879</td>\n",
" <td>19197715</td>\n",
" <td>5102099</td>\n",
" <td>12731</td>\n",
" <td>2055653</td>\n",
" <td>70568038</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>8</td>\n",
" <td>0</td>\n",
" <td>2008</td>\n",
" <td>4nm011118</td>\n",
" <td>xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.11.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности организаций, лик...</td>\n",
" <td>2400</td>\n",
" <td>40157</td>\n",
" <td>71402906</td>\n",
" <td>40477282</td>\n",
" <td>12510111</td>\n",
" <td>3381043</td>\n",
" <td>838205</td>\n",
" <td>1228143</td>\n",
" <td>12968122</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>9</td>\n",
" <td>1</td>\n",
" <td>2008</td>\n",
" <td>4nm011118</td>\n",
" <td>xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.11.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности индивидуальных п...</td>\n",
" <td>2405</td>\n",
" <td>19496</td>\n",
" <td>4481612</td>\n",
" <td>2347431</td>\n",
" <td>1261980</td>\n",
" <td>345253</td>\n",
" <td>628</td>\n",
" <td>72728</td>\n",
" <td>453592</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" global_index ws_index year filename extension ws_title \\\n",
"0 0 0 2009 4nm010618 xlsx Р. Справочно1_Списание \n",
"1 1 1 2009 4nm010618 xlsx Р. Справочно1_Списание \n",
"2 2 2 2009 4nm010618 xlsx Р. Справочно1_Списание \n",
"3 3 3 2009 4nm010618 xlsx Р. Справочно1_Списание \n",
"4 4 4 2009 4nm010618 xlsx Р. Справочно1_Списание \n",
"5 5 5 2009 4nm010618 xlsx Р. Справочно1_Списание \n",
"6 6 6 2009 4nm010618 xlsx Р. Справочно1_Списание \n",
"7 7 7 2009 4nm010618 xlsx Р. Справочно1_Списание \n",
"8 8 0 2008 4nm011118 xlsx Р. Справочно1_Списание \n",
"9 9 1 2008 4nm011118 xlsx Р. Справочно1_Списание \n",
"\n",
" form_name description \\\n",
"0 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"1 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"2 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"3 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"4 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"5 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"6 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"7 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"8 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"9 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"\n",
" form_dt unit_name \\\n",
"0 по состоянию на 01.06.2018 г. тыс. рублей \n",
"1 по состоянию на 01.06.2018 г. тыс. рублей \n",
"2 по состоянию на 01.06.2018 г. тыс. рублей \n",
"3 по состоянию на 01.06.2018 г. тыс. рублей \n",
"4 по состоянию на 01.06.2018 г. тыс. рублей \n",
"5 по состоянию на 01.06.2018 г. тыс. рублей \n",
"6 по состоянию на 01.06.2018 г. тыс. рублей \n",
"7 по состоянию на 01.06.2018 г. тыс. рублей \n",
"8 по состоянию на 01.11.2018 г. тыс. рублей \n",
"9 по состоянию на 01.11.2018 г. тыс. рублей \n",
"\n",
" поле код строки \\\n",
"0 Сумма списанной задолженности организаций, лик... 2400 \n",
"1 Сумма списанной задолженности индивидуальных п... 2405 \n",
"2 Сумма списанной задолженности умерших или объя... 2410 \n",
"3 Сумма списанной задолженности в случаях принят... 2415 \n",
"4 Сумма списанной задолженности по \"зависшим\" пл... 2420 \n",
"5 Сумма списанной задолженности организаций, отв... 2425 \n",
"6 Сумма списанной задолженности по решениям нало... 2430 \n",
"7 Сумма задолженности, списанной на основании з... 2435 \n",
"8 Сумма списанной задолженности организаций, лик... 2400 \n",
"9 Сумма списанной задолженности индивидуальных п... 2405 \n",
"\n",
" кол. налогоплательщиков всего по налогу (сбору) по пени \\\n",
"0 23632 30705385 18388429 4699527 \n",
"1 9109 3013574 1661920 881213 \n",
"2 39920 677495 115346 44047 \n",
"3 58635 2161183 773472 556271 \n",
"4 93 43115 31946 752 \n",
"5 25104 4038755 2487632 1003525 \n",
"6 16841363 60557919 41458668 19050086 \n",
"7 1799585 133435115 36498879 19197715 \n",
"8 40157 71402906 40477282 12510111 \n",
"9 19496 4481612 2347431 1261980 \n",
"\n",
" по штрафам проценты по ЕСН по страховым взносам \n",
"0 1439452 184237 596724 5397016 \n",
"1 242978 628 51928 174907 \n",
"2 11984 0 5203 500915 \n",
"3 70216 5769 154600 600855 \n",
"4 76 0 5527 4814 \n",
"5 215253 х 29516 302829 \n",
"6 325 1 0 48839 \n",
"7 5102099 12731 2055653 70568038 \n",
"8 3381043 838205 1228143 12968122 \n",
"9 345253 628 72728 453592 "
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# пример как полностью настроить класс сразу при создании\n",
"proc = ExcelPreprocessor('data\\\\2009\\\\4nm010618.xlsx', 'data\\\\2008\\\\4nm011118.xlsx',\n",
" filename_parser=lambda filename: re.match(r'data\\\\(?P<year>\\w+)\\\\(?P<filename>\\w+)\\.(?P<extension>\\w+)', filename).groupdict(),\n",
" append_global_index=True, append_wb_index=True,\n",
" cells = {'form_name': 'J1', 'description': 'A2', 'form_dt': 'A3', 'unit_name': 'J4'},\n",
" headers = ['поле', 'код строки', 'кол. налогоплательщиков', 'всего', 'по налогу (сбору)', 'по пени', 'по штрафам', 'проценты', 'по ЕСН', 'по страховым взносам'],\n",
" first_row_number=7, append_ws_title_column=True, iterate_over_worksheet=2\n",
")\n",
"pd.DataFrame(proc.get_iter_dict())[:10]"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"135.86149168014526\n"
]
}
],
"source": [
"fn = r'C:\\dev\\.jupyter\\water\\water_report.zip'\n",
"proc = ExcelPreprocessor(fn,\n",
" filename_parser=lambda filename: {'filename': filename.split('.')[0]},\n",
" append_global_index=True, append_wb_index=True,\n",
" cells = {'obj': 'A1', 'form_dt': 'A2', 'report_dt': 'A3', 'np': 'B7'},\n",
" headers = ['col_%s' % i for i in range(1, 39)],\n",
" first_row_number=7, append_ws_title_column=True, iterate_over_worksheet=0\n",
")\n",
"import time\n",
"ct = time.time()\n",
"d = pd.DataFrame(proc.get_iter_dict())\n",
"print(time.time() - ct)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>global_index</th>\n",
" <th>ws_index</th>\n",
" <th>filename</th>\n",
" <th>ws_title</th>\n",
" <th>form_name</th>\n",
" <th>description</th>\n",
" <th>form_dt</th>\n",
" <th>unit_name</th>\n",
" <th>поле</th>\n",
" <th>код строки</th>\n",
" <th>кол. налогоплательщиков</th>\n",
" <th>всего</th>\n",
" <th>по налогу (сбору)</th>\n",
" <th>по пени</th>\n",
" <th>по штрафам</th>\n",
" <th>проценты</th>\n",
" <th>по ЕСН</th>\n",
" <th>по страховым взносам</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>4nm010318.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.03.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности организаций, лик...</td>\n",
" <td>2400</td>\n",
" <td>6302</td>\n",
" <td>8850836</td>\n",
" <td>4813849</td>\n",
" <td>1428282</td>\n",
" <td>385722</td>\n",
" <td>122790</td>\n",
" <td>249262</td>\n",
" <td>1850931</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>4nm010318.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.03.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности индивидуальных п...</td>\n",
" <td>2405</td>\n",
" <td>3901</td>\n",
" <td>891751</td>\n",
" <td>515082</td>\n",
" <td>267015</td>\n",
" <td>59948</td>\n",
" <td>0</td>\n",
" <td>18923</td>\n",
" <td>30783</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>2</td>\n",
" <td>2</td>\n",
" <td>4nm010318.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.03.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности умерших или объя...</td>\n",
" <td>2410</td>\n",
" <td>12387</td>\n",
" <td>285449</td>\n",
" <td>45580</td>\n",
" <td>23315</td>\n",
" <td>9378</td>\n",
" <td>0</td>\n",
" <td>2264</td>\n",
" <td>204912</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>3</td>\n",
" <td>3</td>\n",
" <td>4nm010318.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.03.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности в случаях принят...</td>\n",
" <td>2415</td>\n",
" <td>19761</td>\n",
" <td>883355</td>\n",
" <td>327372</td>\n",
" <td>193665</td>\n",
" <td>35799</td>\n",
" <td>5646</td>\n",
" <td>79245</td>\n",
" <td>241628</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>4</td>\n",
" <td>4</td>\n",
" <td>4nm010318.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.03.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности по \"зависшим\" пл...</td>\n",
" <td>2420</td>\n",
" <td>46</td>\n",
" <td>17476</td>\n",
" <td>16940</td>\n",
" <td>9</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>527</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>5</td>\n",
" <td>5</td>\n",
" <td>4nm010318.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.03.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности организаций, отв...</td>\n",
" <td>2425</td>\n",
" <td>11847</td>\n",
" <td>1198159</td>\n",
" <td>675557</td>\n",
" <td>308155</td>\n",
" <td>82420</td>\n",
" <td>х</td>\n",
" <td>14139</td>\n",
" <td>117888</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>6</td>\n",
" <td>6</td>\n",
" <td>4nm010318.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.03.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности по решениям нало...</td>\n",
" <td>2430</td>\n",
" <td>61</td>\n",
" <td>37</td>\n",
" <td>1</td>\n",
" <td>31</td>\n",
" <td>5</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>7</td>\n",
" <td>7</td>\n",
" <td>4nm010318.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.03.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма задолженности, списанной на основании з...</td>\n",
" <td>2435</td>\n",
" <td>1148327</td>\n",
" <td>40739221</td>\n",
" <td>21970735</td>\n",
" <td>12925353</td>\n",
" <td>3832251</td>\n",
" <td>4354</td>\n",
" <td>107461</td>\n",
" <td>1899067</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>8</td>\n",
" <td>0</td>\n",
" <td>4nm010218.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.02.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности организаций, лик...</td>\n",
" <td>2400</td>\n",
" <td>2768</td>\n",
" <td>4066983</td>\n",
" <td>2314354</td>\n",
" <td>735408</td>\n",
" <td>187148</td>\n",
" <td>39881</td>\n",
" <td>86601</td>\n",
" <td>703591</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>9</td>\n",
" <td>1</td>\n",
" <td>4nm010218.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.02.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности индивидуальных п...</td>\n",
" <td>2405</td>\n",
" <td>3067</td>\n",
" <td>39999</td>\n",
" <td>21675</td>\n",
" <td>12298</td>\n",
" <td>3944</td>\n",
" <td>0</td>\n",
" <td>681</td>\n",
" <td>1401</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>10</td>\n",
" <td>2</td>\n",
" <td>4nm010218.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.02.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности умерших или объя...</td>\n",
" <td>2410</td>\n",
" <td>5411</td>\n",
" <td>145804</td>\n",
" <td>25389</td>\n",
" <td>15249</td>\n",
" <td>6433</td>\n",
" <td>0</td>\n",
" <td>1198</td>\n",
" <td>97535</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>11</td>\n",
" <td>3</td>\n",
" <td>4nm010218.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.02.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности в случаях принят...</td>\n",
" <td>2415</td>\n",
" <td>14035</td>\n",
" <td>330592</td>\n",
" <td>101728</td>\n",
" <td>66280</td>\n",
" <td>8424</td>\n",
" <td>8</td>\n",
" <td>13190</td>\n",
" <td>140962</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>12</td>\n",
" <td>4</td>\n",
" <td>4nm010218.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.02.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности по \"зависшим\" пл...</td>\n",
" <td>2420</td>\n",
" <td>27</td>\n",
" <td>7852</td>\n",
" <td>7744</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>108</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>13</td>\n",
" <td>5</td>\n",
" <td>4nm010218.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.02.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности организаций, отв...</td>\n",
" <td>2425</td>\n",
" <td>4917</td>\n",
" <td>714015</td>\n",
" <td>394956</td>\n",
" <td>184775</td>\n",
" <td>43302</td>\n",
" <td>х</td>\n",
" <td>7748</td>\n",
" <td>83234</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>14</td>\n",
" <td>6</td>\n",
" <td>4nm010218.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.02.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма списанной задолженности по решениям нало...</td>\n",
" <td>2430</td>\n",
" <td>14</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>2</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>15</td>\n",
" <td>7</td>\n",
" <td>4nm010218.xlsx</td>\n",
" <td>Р. Справочно1_Списание</td>\n",
" <td>Форма № 4-НМ</td>\n",
" <td>Справочно к Разделам I, II: 1_Списано зад...</td>\n",
" <td>по состоянию на 01.02.2018 г.</td>\n",
" <td>тыс. рублей</td>\n",
" <td>Сумма задолженности, списанной на основании з...</td>\n",
" <td>2435</td>\n",
" <td>41695</td>\n",
" <td>5152573</td>\n",
" <td>2928511</td>\n",
" <td>1090182</td>\n",
" <td>258133</td>\n",
" <td>3456</td>\n",
" <td>36947</td>\n",
" <td>835344</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" global_index ws_index filename ws_title \\\n",
"0 0 0 4nm010318.xlsx Р. Справочно1_Списание \n",
"1 1 1 4nm010318.xlsx Р. Справочно1_Списание \n",
"2 2 2 4nm010318.xlsx Р. Справочно1_Списание \n",
"3 3 3 4nm010318.xlsx Р. Справочно1_Списание \n",
"4 4 4 4nm010318.xlsx Р. Справочно1_Списание \n",
"5 5 5 4nm010318.xlsx Р. Справочно1_Списание \n",
"6 6 6 4nm010318.xlsx Р. Справочно1_Списание \n",
"7 7 7 4nm010318.xlsx Р. Справочно1_Списание \n",
"8 8 0 4nm010218.xlsx Р. Справочно1_Списание \n",
"9 9 1 4nm010218.xlsx Р. Справочно1_Списание \n",
"10 10 2 4nm010218.xlsx Р. Справочно1_Списание \n",
"11 11 3 4nm010218.xlsx Р. Справочно1_Списание \n",
"12 12 4 4nm010218.xlsx Р. Справочно1_Списание \n",
"13 13 5 4nm010218.xlsx Р. Справочно1_Списание \n",
"14 14 6 4nm010218.xlsx Р. Справочно1_Списание \n",
"15 15 7 4nm010218.xlsx Р. Справочно1_Списание \n",
"\n",
" form_name description \\\n",
"0 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"1 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"2 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"3 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"4 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"5 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"6 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"7 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"8 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"9 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"10 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"11 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"12 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"13 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"14 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"15 Форма № 4-НМ Справочно к Разделам I, II: 1_Списано зад... \n",
"\n",
" form_dt unit_name \\\n",
"0 по состоянию на 01.03.2018 г. тыс. рублей \n",
"1 по состоянию на 01.03.2018 г. тыс. рублей \n",
"2 по состоянию на 01.03.2018 г. тыс. рублей \n",
"3 по состоянию на 01.03.2018 г. тыс. рублей \n",
"4 по состоянию на 01.03.2018 г. тыс. рублей \n",
"5 по состоянию на 01.03.2018 г. тыс. рублей \n",
"6 по состоянию на 01.03.2018 г. тыс. рублей \n",
"7 по состоянию на 01.03.2018 г. тыс. рублей \n",
"8 по состоянию на 01.02.2018 г. тыс. рублей \n",
"9 по состоянию на 01.02.2018 г. тыс. рублей \n",
"10 по состоянию на 01.02.2018 г. тыс. рублей \n",
"11 по состоянию на 01.02.2018 г. тыс. рублей \n",
"12 по состоянию на 01.02.2018 г. тыс. рублей \n",
"13 по состоянию на 01.02.2018 г. тыс. рублей \n",
"14 по состоянию на 01.02.2018 г. тыс. рублей \n",
"15 по состоянию на 01.02.2018 г. тыс. рублей \n",
"\n",
" поле код строки \\\n",
"0 Сумма списанной задолженности организаций, лик... 2400 \n",
"1 Сумма списанной задолженности индивидуальных п... 2405 \n",
"2 Сумма списанной задолженности умерших или объя... 2410 \n",
"3 Сумма списанной задолженности в случаях принят... 2415 \n",
"4 Сумма списанной задолженности по \"зависшим\" пл... 2420 \n",
"5 Сумма списанной задолженности организаций, отв... 2425 \n",
"6 Сумма списанной задолженности по решениям нало... 2430 \n",
"7 Сумма задолженности, списанной на основании з... 2435 \n",
"8 Сумма списанной задолженности организаций, лик... 2400 \n",
"9 Сумма списанной задолженности индивидуальных п... 2405 \n",
"10 Сумма списанной задолженности умерших или объя... 2410 \n",
"11 Сумма списанной задолженности в случаях принят... 2415 \n",
"12 Сумма списанной задолженности по \"зависшим\" пл... 2420 \n",
"13 Сумма списанной задолженности организаций, отв... 2425 \n",
"14 Сумма списанной задолженности по решениям нало... 2430 \n",
"15 Сумма задолженности, списанной на основании з... 2435 \n",
"\n",
" кол. налогоплательщиков всего по налогу (сбору) по пени \\\n",
"0 6302 8850836 4813849 1428282 \n",
"1 3901 891751 515082 267015 \n",
"2 12387 285449 45580 23315 \n",
"3 19761 883355 327372 193665 \n",
"4 46 17476 16940 9 \n",
"5 11847 1198159 675557 308155 \n",
"6 61 37 1 31 \n",
"7 1148327 40739221 21970735 12925353 \n",
"8 2768 4066983 2314354 735408 \n",
"9 3067 39999 21675 12298 \n",
"10 5411 145804 25389 15249 \n",
"11 14035 330592 101728 66280 \n",
"12 27 7852 7744 0 \n",
"13 4917 714015 394956 184775 \n",
"14 14 2 0 2 \n",
"15 41695 5152573 2928511 1090182 \n",
"\n",
" по штрафам проценты по ЕСН по страховым взносам \n",
"0 385722 122790 249262 1850931 \n",
"1 59948 0 18923 30783 \n",
"2 9378 0 2264 204912 \n",
"3 35799 5646 79245 241628 \n",
"4 0 0 527 0 \n",
"5 82420 х 14139 117888 \n",
"6 5 0 0 0 \n",
"7 3832251 4354 107461 1899067 \n",
"8 187148 39881 86601 703591 \n",
"9 3944 0 681 1401 \n",
"10 6433 0 1198 97535 \n",
"11 8424 8 13190 140962 \n",
"12 0 0 108 0 \n",
"13 43302 х 7748 83234 \n",
"14 0 0 0 0 \n",
"15 258133 3456 36947 835344 "
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# пример как полностью настроить класс сразу при создании\n",
"proc = ExcelPreprocessor(\n",
" 'https://www.nalog.ru/html/sites/www.new.nalog.ru/docs/otchet/4nm010318.xlsx',\n",
" 'https://www.nalog.ru/html/sites/www.new.nalog.ru/docs/otchet/4NM/4nm010218.xlsx',\n",
" filename_parser=lambda filename: {'filename': filename.split('/')[-1]},\n",
" append_global_index=True, append_wb_index=True,\n",
" cells = {'form_name': 'J1', 'description': 'A2', 'form_dt': 'A3', 'unit_name': 'J4'},\n",
" headers = ['поле', 'код строки', 'кол. налогоплательщиков', 'всего', 'по налогу (сбору)', 'по пени', 'по штрафам', 'проценты', 'по ЕСН', 'по страховым взносам'],\n",
" first_row_number=7, append_ws_title_column=True, iterate_over_worksheet=2\n",
")\n",
"pd.DataFrame(proc.get_iter_dict())"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.2"
}
},
"nbformat": 4,
"nbformat_minor": 4
}