{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# 2A.i - Table de mortalit\u00e9 dans plusieurs containers\n", "\n", "Pas de calcul d'esp\u00e9rence de vie, seulement diff\u00e9rentes fa\u00e7ons de lire les donn\u00e9es d'une table de mortalit\u00e9."]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": ["%matplotlib inline\n", "import matplotlib.pyplot as plt"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [{"data": {"text/html": ["
run previous cell, wait for 2 seconds
\n", ""], "text/plain": [""]}, "execution_count": 3, "metadata": {}, "output_type": "execute_result"}], "source": ["from jyquickhelper import add_notebook_menu\n", "add_notebook_menu()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## R\u00e9cup\u00e9ration des donn\u00e9es\n", "\n", "Les donn\u00e9es sont recens\u00e9es sur [Data Publica](http://www.data-publica.com/) : [Table de mortalit\u00e9](http://www.data-publica.com/opendata/7098--population-et-conditions-sociales-table-de-mortalite-de-1960-a-2010) qui les a r\u00e9cup\u00e9r\u00e9 depuis le site d'Eurostat via le listing suivant : [listing](http://epp.eurostat.ec.europa.eu/NavTree_prod/everybody/BulkDownloadListing?sort=1&dir=data). Pour faire court, le lien est le suivant : [demo_mlifetable.tsv.gz](http://epp.eurostat.ec.europa.eu/NavTree_prod/everybody/BulkDownloadListing?file=data/demo_mlifetable.tsv.gz). Le fichier est compress\u00e9 au format [gzip](http://fr.wikipedia.org/wiki/Gzip). On le t\u00e9l\u00e9charge, on le d\u00e9compresse."]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": ["url = \"http://ec.europa.eu/eurostat/estat-navtree-portlet-prod/BulkDownloadListing?file=data/\"\n", "file = \"demo_mlifetable.tsv.gz\"\n", "import pyensae.datasource\n", "local = pyensae.datasource.download_data(\"demo_mlifetable.tsv.gz\", url=url)\n", "local = local[0]+\".gz\"\n", "import gzip\n", "with gzip.open(local, 'rb') as f: \n", " file_content = f.read()\n", "content = str(file_content, encoding=\"utf8\")\n", "with open(\"mortalite.txt\", \"w\", encoding=\"utf8\") as f:\n", " f.write(content)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Puis on le charge sous forme de dataframe :"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
indic_de,sex,age,geo\\time201920182017201620152014201320122011...1969196819671966196519641963196219611960
0DEATHRATE,F,Y1,AL0.000210.000670.000460.000430.000420.000420.00110::...::::::::::
1DEATHRATE,F,Y1,AM0.000510.000430.000520.000350.00035::::...::::::::::
2DEATHRATE,F,Y1,AT0.000260.000210.000170.000270.000170.000150.000160.000180.00018...::::::::::
3DEATHRATE,F,Y1,AZ0.000720.000410.00081:0.000900.000920.000700.00132:...::::::::::
4DEATHRATE,F,Y1,BE0.000240.000220.000280.000250.000340.000350.000360.000250.00030...0.001410.001550.001320.001290.001530.001370.001700.001610.001680.00159
\n", "

5 rows \u00d7 61 columns

\n", "
"], "text/plain": [" indic_de,sex,age,geo\\time 2019 2018 2017 2016 2015 \\\n", "0 DEATHRATE,F,Y1,AL 0.00021 0.00067 0.00046 0.00043 0.00042 \n", "1 DEATHRATE,F,Y1,AM 0.00051 0.00043 0.00052 0.00035 0.00035 \n", "2 DEATHRATE,F,Y1,AT 0.00026 0.00021 0.00017 0.00027 0.00017 \n", "3 DEATHRATE,F,Y1,AZ 0.00072 0.00041 0.00081 : 0.00090 \n", "4 DEATHRATE,F,Y1,BE 0.00024 0.00022 0.00028 0.00025 0.00034 \n", "\n", " 2014 2013 2012 2011 ... 1969 1968 1967 \\\n", "0 0.00042 0.00110 : : ... : : : \n", "1 : : : : ... : : : \n", "2 0.00015 0.00016 0.00018 0.00018 ... : : : \n", "3 0.00092 0.00070 0.00132 : ... : : : \n", "4 0.00035 0.00036 0.00025 0.00030 ... 0.00141 0.00155 0.00132 \n", "\n", " 1966 1965 1964 1963 1962 1961 1960 \n", "0 : : : : : : : \n", "1 : : : : : : : \n", "2 : : : : : : : \n", "3 : : : : : : : \n", "4 0.00129 0.00153 0.00137 0.00170 0.00161 0.00168 0.00159 \n", "\n", "[5 rows x 61 columns]"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["import pandas\n", "dff = pandas.read_csv(\"mortalite.txt\", sep=\"\\t\", encoding=\"utf8\")\n", "dff.head()"]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"data": {"text/plain": ["(101136, 61)"]}, "execution_count": 6, "metadata": {}, "output_type": "execute_result"}], "source": ["dff.shape"]}, {"cell_type": "markdown", "metadata": {}, "source": ["La premi\u00e8re colonne contient une aggr\u00e9gation de champs. On souhaite transformer cette table de telle sorte qu'on ait un nombre r\u00e9duit de colonnes :\n", "\n", "- indicateur\n", "- genre\n", "- age\n", "- pays (ou ensemble de pays)\n", "- annee\n", "- valeur\n", "\n", "L'\u00e2ge est repr\u00e9sent\u00e9 sous forme de cha\u00eene de caract\u00e8res pour pouvoir \u00e9crire ``Y_LT1`` (moins d'un an), ``Y_GE85`` (plus de 85 ans). On change un peu le format pour pouvoir les trier par ordre croissant (en effet ``Y2`` est apr\u00e8s ``Y10``). On sauve le tout dans un fichier pour ne pas avoir \u00e0 recommencer ult\u00e9rieurement. Malgr\u00e9 tout, le code ci-dessous est tr\u00e8s lent pour la table compl\u00e8te qui contiendra au final pr\u00e8s de 5 millions de lignes. On supprime les valeurs manquantes."]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["\u00e9tape 1 (101136, 61)\n", "\u00e9tape 2 (6068160, 1)\n", "\u00e9tape 3 (3254823, 3)\n", "\u00e9tape 4\n"]}, {"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
anneevaleurageindicateurgenrepays
020190.00021Y01DEATHRATEFAL
120180.00067Y01DEATHRATEFAL
220170.00046Y01DEATHRATEFAL
320160.00043Y01DEATHRATEFAL
420150.00042Y01DEATHRATEFAL
\n", "
"], "text/plain": [" annee valeur age indicateur genre pays\n", "0 2019 0.00021 Y01 DEATHRATE F AL\n", "1 2018 0.00067 Y01 DEATHRATE F AL\n", "2 2017 0.00046 Y01 DEATHRATE F AL\n", "3 2016 0.00043 Y01 DEATHRATE F AL\n", "4 2015 0.00042 Y01 DEATHRATE F AL"]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}], "source": ["def format_age(s):\n", " if s.startswith(\"Y_\") : \n", " if s.startswith(\"Y_LT\"): s = \"Y00_LT\" + s[4:]\n", " elif s.startswith(\"Y_GE\"): s = \"Y85_GE\" + s[4:]\n", " else: raise FormatError(s)\n", " else:\n", " i = int(s.strip(\"Y\"))\n", " return \"Y%02d\" % i\n", " \n", "def format_value(s):\n", " if s.strip() == \":\" : return -1\n", " else : return float(s.strip(\" ebp\"))\n", " \n", "if False: # sur les donn\u00e9es compl\u00e8tes, c'est plut\u00f4t long, r\u00e9duire la taille pour essayer\n", " dfsmall = dff.head(n = 1000) # on r\u00e9duit la taille pour \n", " df = dfsmall # impl\u00e9menter la transformation\n", "else:\n", " df = dff\n", "\n", "print(\"\u00e9tape 1\", df.shape)\n", "dfi = df.reset_index().set_index(\"indic_de,sex,age,geo\\\\time\")\n", "dfi = dfi.drop('index', axis=1)\n", "dfs = dfi.stack()\n", "dfs = pandas.DataFrame({\"valeur\": dfs } )\n", "\n", "print(\"\u00e9tape 2\", dfs.shape)\n", "dfs[\"valeur\"] = dfs[\"valeur\"].astype(str)\n", "dfs[\"valeur\"] = dfs[\"valeur\"].apply( format_value )\n", "dfs = dfs[ dfs.valeur >= 0 ].copy()\n", "dfs = dfs.reset_index()\n", "dfs.columns = [\"index\", \"annee\", \"valeur\"]\n", "\n", "print(\"\u00e9tape 3\", dfs.shape)\n", "dfs[\"age\"] = dfs[\"index\"].apply ( lambda i : format_age(i.split(\",\")[2]))\n", "dfs[\"indicateur\"] = dfs[\"index\"].apply ( lambda i : i.split(\",\")[0])\n", "dfs[\"genre\"] = dfs[\"index\"].apply ( lambda i : i.split(\",\")[1])\n", "dfs[\"pays\"] = dfs[\"index\"].apply ( lambda i : i.split(\",\")[3])\n", "\n", "print(\"\u00e9tape 4\")\n", "dfy = dfs.drop('index', axis=1)\n", "dfy.to_csv(\"mortalite_5column.txt\", sep=\"\\t\", encoding=\"utf8\", index=False)\n", "dfy.head()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Graphe d'une coupe de la table de mortalit\u00e9 :"]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"data": {"image/png": "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\n", "text/plain": ["
"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["view = dfs [ (dfs.pays==\"FR\") &\n", " (dfs.age == \"Y80\") &\n", " (dfs.indicateur == \"DEATHRATE\") &\n", " (dfs.genre == \"T\") ]\n", "view = view.sort_values(\"annee\")\n", "view.plot(x=\"annee\", y=\"valeur\");"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### SQLite\n", "\n", "[SQLite](http://www.sqlite.org/) est un outils de gestion de base de donn\u00e9es locales. Int\u00e9gr\u00e9 \u00e0 Python, il ne n\u00e9cessite aucune installation. Il est tr\u00e8s utile lorsque [Microsoft Excel](http://fr.wikipedia.org/wiki/Microsoft_Excel) ne peut pas contenir toutes les donn\u00e9es qu'on souhaite consulter. Plus de deux millions de lignes dans le cas de cette table."]}, {"cell_type": "markdown", "metadata": {}, "source": ["### version 1 : pandas to SQLite\n", "\n", "On utilise pour la m\u00e9thode [to_sql](http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.to_sql.html) et le module [sqlite3](https://docs.python.org/3.4/library/sqlite3.html). Ca prend un peu de temps (deux \u00e0 trois minutes)."]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": ["import sqlite3\n", "con = sqlite3.connect(\"mortalite_sqlite3_y2.db3\")\n", "dfy.to_sql(\"table_mortalite\",con)\n", "con.close() # il faut fermer la base qui sinon reste ouverte tant que le notebook\n", " # n'est pas ferm\u00e9 --> elle n'est pas modifiable pas d'autre que ce notebook"]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"data": {"text/plain": ["['mortalite_sqlite3_y2.db3']"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["import os\n", "[ _ for _ in os.listdir(\".\") if \"sqlite3\" in _ ]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On utilise une requ\u00eate SQL pour r\u00e9cup\u00e9rer les donn\u00e9es \u00e9quivalent au code pandas cit\u00e9 ci-dessous :"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": ["con = sqlite3.connect(\"mortalite_sqlite3_y2.db3\")\n", "view = pandas.read_sql(\"\"\"SELECT * FROM table_mortalite WHERE pays==\"FR\" \n", " AND age == \"Y80\" \n", " AND indicateur == \"DEATHRATE\"\n", " AND genre == \"T\"\n", " ORDER BY annee\"\"\", con)\n", "con.close()"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"data": {"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYcAAAEGCAYAAACO8lkDAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8/fFQqAAAACXBIWXMAAAsTAAALEwEAmpwYAAA220lEQVR4nO3deXxU1fn48c8zk40lJBASCISQsIUl7GFHBQUFq6B1AW3damutWqv+2qpdLGrr161u1WqtaNGqSHFDq4IbIqBA2HcIewJkAwJhy/b8/pgbOyYhmSSTDBme9+s1r9w599wzz72QeXLvOfdcUVWMMcYYb65AB2CMMeb0Y8nBGGNMJZYcjDHGVGLJwRhjTCWWHIwxxlQSEugA/KFt27aalJQU6DCMMaZJWb58eZ6qxla1LiiSQ1JSEunp6YEOwxhjmhQR2XWqdXZZyRhjTCWWHIwxxlRiycEYY0wlQdHnYIwxFRUXF5OZmcmJEycCHUrARUREkJCQQGhoqM/bWHIwxgSlzMxMIiMjSUpKQkQCHU7AqCr5+flkZmaSnJzs83Z2WckYE5ROnDhBTEzMGZ0YAESEmJiYWp9BWXIwxgStMz0xlKvLcbDk0MiyD5/g/VVZgQ7DGGOqZcmhkT0/fxu/mrmKVXsOBToUY8xppmXLloEO4TuWHBrZoow8AGYs3hnYQIwxQaukpKTebVhyaETZh0+wNaeQ6OahfLhmLzmHbYidMcHsnnvu4bnnnvvu/bRp0/jzn//Meeedx6BBg+jbty/vv/9+lds+9thjDBkyhH79+vGnP/0JgJ07d5Kamvpdnccff5xp06YBMGbMGO644w7S0tJ4+umn6x37GT2UdX/BCZbvOsgP+sU3yueVnzX8+ZJUfvnmSl5fsps7x/dolM825kx2/wfr2bD3sF/b7N2hFX+6uE+1daZMmcIdd9zBrbfeCsCsWbOYO3cut99+O61atSIvL4/hw4czadKk73Uaz5s3j61bt7J06VJUlUmTJrFgwQISExOr/byioiK/zTN3Rp85vL0ik1vfWNFof8EvzMijdfNQLkyNZ2xKHK8v2c3JktJG+WxjTOMbOHAgOTk57N27l9WrV9O6dWvat2/P7373O/r168e4cePIysoiOzv7e9vNmzePefPmMXDgQAYNGsSmTZvYunVrjZ83ZcoUv8V+Rp85jEmJ5bG5m5m/JZcr0zo16GepKosy8hjZrS0ul3D9yCSufXkp/12zjx8OSmjQzzbmTFfTX/gN6YorrmD27Nns37+fKVOm8Prrr5Obm8vy5csJDQ0lKSmp0j0Iqsq9997Lz3/+8++VZ2ZmUlZW9t37itu1aNHCb3Gf0WcOveNbERcZzlebcxv8s7blFpJ9+CSju7UF4Kzubeka24JXFu1EVRv8840xgTFlyhRmzpzJ7NmzueKKKygoKCAuLo7Q0FC+/PJLdu2qPGv2BRdcwMsvv0xhYSEAWVlZ5OTk0K5dO3JycsjPz+fkyZN8+OGHDRa3T8lBRCaIyGYRyRCRe6pYHy4ibznrl4hIklOeJCLHRWSV83rBKW8uIv8VkU0isl5EHvZq63oRyfXa5qd+2teq9osxKbEs2JpLSWlZzRvUw8Ktnv6G8uQgIlw/Kpm1WQWs2H2wQT/bGBM4ffr04ciRI3Ts2JH4+Hh+9KMfkZ6eTt++fXn11Vfp2bNnpW3OP/98rr76akaMGEHfvn25/PLLOXLkCKGhodx3330MHTqU8ePHV7mt36hqtS/ADWwDugBhwGqgd4U6twAvOMtTgbec5SRgXRVtNgfGOsthwNfAROf99cCzNcXl/Ro8eLDW1Udr9mrnuz/UJdvz69yGL346Y5me9cgX3ysrPFGsqX/6RG99fXmDfrYxZ6INGzYEOoTTSlXHA0jXU3yv+nLmMBTIUNXtqloEzAQmV6gzGZjhLM8GzpNq7tdW1WOq+qWzXASsAAJy4X1U97aEuIQvN+c02GeUlJbx7bZ8RjlnDeVahIcwdUgnPl63n30Fxxvs840xprZ8SQ4dgT1e7zOdsirrqGoJUADEOOuSRWSliHwlImdVbFxEooGLgc+9ii8TkTUiMltEquwpFpGbRCRdRNJzc+veZ9AqIpTBnVvz5aaGSw5rsgo4crLku0tK3q4dkUSZKv/+9pRP6zPGmEbX0B3S+4BEVR0I3AW8ISKtyleKSAjwJvCMqm53ij8AklS1H/Ap/zsj+R5VfVFV01Q1LTa2yudj+2xMShyb9h9hf0HDDGldtDUPERjRNabSuk5tmjOuVzveWLKbE8U2rNUYf1Ib7AHU7Tj4khyyAO+/3hOcsirrOF/4UUC+qp5U1XwnuOV4+i687/p6Ediqqk+VF6hqvqqedN6+BAz2eW/qaGxPT3KZ30CXlhZm5NGnQyvatAircv0No5I4eKyYOav3NsjnG3MmioiIID8//4xPEOo8zyEiIqJW2/lyn8MyoLuIJONJAlOBqyvUmQNcB3wDXA58oaoqIrHAAVUtFZEuQHdgO4CI/BlPEvneaCQRiVfVfc7bScDGWu1RHaS0iyQ+KoL5m3OZOrT6OxBr61hRCSt2H+Qno0/9kI0RXWJIaRfJK4t2csXgBJtm2Bg/SEhIIDMzk/pcdg4W5U+Cq40ak4OqlojIbcBcPCOXXlbV9SLyAJ6e7jnAdOA1EckADuBJIABnAw+ISDFQBtysqgdEJAH4PbAJWOF8GT6rqi8Bt4vIJKDEaev6Wu1RHZQPaf1g9T6KSsoIC/Hf1balOw5QXKpV9jd4f/4No5K45521LN1xgGFdKl9+MsbUTmhoaK2efGa+z6c7pFX1I+CjCmX3eS2fAK6oYru3gberKM8EqvzzWFXvBe71JS5/GpMSx5tL95C+6wAju576i7y2FmXkEeZ2kda5TbX1Jg/oyMOfbOKVRTstORhjAu6MvkPa26hubQl1i9/vll6Ykc/gzq1pFuautl6zMDdThyQyb8N+Mg8e82sMxhhTW5YcHC3DQxiS1Mav9zvkFZ5k477DjO7u25nINSM6IyK8ZsNajTEBZsnBy9iUOLZkF5J1yD83pC3elg9Q6ea3U+kY3YwL+rRj5tI9HCuq/8M6jDGmriw5eBmT4t8hrYu25hEZEULfjlE+b3PDqGQKjhfz3kob1mqMCRxLDl66xbWkY3Qz5vuh30FVWZiRx8iuMbhdvg9NTevcmj4dWvGvxTvO+PHZxpjAseTgpXxI66KMvHo/hGdX/jGyDh2vdgjrqWK4fmQSW7ILv7ssZYwxjc2SQwVjU+I4VlTKsh31m0Z70TbPFN2+9jd4u7h/B2JahPHKop31isEYY+rKkkMFI7vFEOZ21bvfYVFGHh2iIkhuW/snM0WEurl6WCKfb8pmV/7ResVhjDF1YcmhguZhIQzrUr8hraVlymJniu66ToXx4+GdcYvw6jc2rNUY0/gsOVRhTEoc23KPsudA3W5G27D3MIeOFft8f0NV2rWK4MK+8cxatoejJ21YqzGmcVlyqEJ9h7QuzPD0N9R3Go7rRyVx5GQJb6/IrFc7xhhTW5YcqtClbQsS2zTnyzoOaV2UkUfP9pHERobXK45Bia3p3ymafy3eSVmZDWs1xjQeSw5VEBHGpsSyeFterR/Ac6K4lKU7D9RplFJVbhiZxPbco3ztnI0YY0xjsORwCmNS4jhRXMaSHQdqtd3yXQcpKiljVDf/zKx6Yd94YiPDeWXRDr+0Z4wxvrDkcArDu8QQHlL7Ia0LM/IIcQlDk/2THMJCXPx4WGfmb85le26hX9o0xpiaWHI4hWZhbkZ0jan1VBqLMvIYmBhNy3CfHpXhk6uHJRLmdjFj8U6/tWmMMdXxKTmIyAQR2SwiGSJyTxXrw0XkLWf9EhFJcsqTROS4iKxyXi94bTNYRNY62zwjzg0BItJGRD4Vka3Oz9Z+2tdaG9Mjlh15R9mZ59uNaIeOFbE2q8Bv/Q3lYiPDuah/PLOXZ3L4RLFf2zbGmKrUmBxExA08B0wEegNXiUjvCtVuBA6qajfgSeARr3XbVHWA87rZq/x54Gd4nivdHZjglN8DfK6q3YHPnfcBMSYlDvB9SOs32/JRpdbzKfnihpHJHC0q5aH/bqz3vE/GGFMTX84chgIZqrpdVYuAmcDkCnUmAzOc5dnAeVLNrcEiEg+0UtVv1TP16KvAJVW0NcOrvNEltW1BctsWPg9pXZiRR4swN/07Rfs9lr4JUfx0dDIzl+3h0ucWk5FzxO+fYYwx5XxJDh2BPV7vM52yKuuoaglQAJT3yCaLyEoR+UpEzvKq731nl3eb7VR1n7O8H2hXVVAicpOIpItIem6ufx/t6W1MSizfbs/neFHNf60vyshjeJcYQt0N05Xzh4t689K1aew/fIKL/raQf3+7y6b1NsY0iIbukN4HJKrqQOAu4A0RaeXrxs5ZRZXffqr6oqqmqWpabGysf6KtwtiUOE6WlPHt9uqnz848eIyd+cf83t9Q0bje7fjkV2cxJKkNf3hvHTe9tpwDR4sa9DONMWceX5JDFtDJ632CU1ZlHREJAaKAfFU9qar5AKq6HNgG9HDqJ5yizWznslP55Sf/PdS5DoYmt6FZqLvGfofFGZ7kUZ/5lHwV1yqCGTcM5Y8X9earzblc8NQCvt7acGdPxpgzjy/JYRnQXUSSRSQMmArMqVBnDnCds3w58IWqqojEOh3aiEgXPB3P253LRodFZLjTN3Et8H4VbV3nVR4QEaFuRnaN4cvNudVewlmYkUdsZDjd41o2Slwul3Dj6GTeu3UU0c1CuWb6Uv784QbrrDbG+EWNycHpQ7gNmAtsBGap6noReUBEJjnVpgMxIpKB5/JR+Qijs4E1IrIKT0f1zapafsvxLcBLQAaeM4qPnfKHgfEishUY57wPqDEpsew+cIwdpxjSWlamLMrIY3Q9puiuq94dWjHnttFcM7wzLy3cYZ3Vxhi/8OlOLVX9CPioQtl9XssngCuq2O5t4O1TtJkOpFZRng+c50tcjcUzpHU9X27OpUts5TODzdlHyD9a1OD9DafSLMzNg5ekck6PWH779hp+8MxC/nBRb348LLFOyepYUQlrMgtYufsQ6/cWcP3IJNKS2jRA5MaY05X/buMNYp3aNKdbXEvmb87hxtHJldYvyih/JKh/psyoq3G92/FJwln8v/+s5o/vreOrzbk8cllfYlqeenZYVWVH3lFW7j7Eyj0HWbHrEJuzj1DqzALrdgnHi0qZfr0lB2POJJYcfDSmRyyvfrOLY0UlNA/7/mFbmJFH19gWxEc1C1B0/1PeWf3K4p088vEmJjz9NU9c2Z+zuntGdBUcL2b1nkPfJYNVew5x6JjnruvI8BAGJEZza6+uDExszYBO0fztiwz+/e0uCk+W+HVKEGPM6c1+2300tmccLy3cweKMfMb1/t+tF0UlZSzZfoAr0xKq2bpxlXdWj+gSw69mruSa6Us5t2ccuw8cIyPHM3mfCPSIi2RCn/YMTIxmYGJrusW2xOX6/mWoiX3b8/KiHXyxKYdJ/TsEYneMMQFgycFHaUmtaR7mZv6WnO8lh5W7D3K8uJSRAepvqE7vDq344Jej+b+PNvLphmx6xbfikgEdGJjYmn4JUURGhNbYxqDE1rRtGc7cdfstORhzBrHk4KPwEDejurXly02eIa3lHb2LMvJwiWeK79NRRKib+yencv/kSn3/PnG7hAv6tOPdlVmcKC4lItTt5wiNMacjm7K7FsamxJF16Ph3l2bA09/QLyGaqGY1/xXeVE1Ibc+xolIWbLEb7Yw5U1hyqIUxKZ5O3fJnPBw+UczqzIIGmYX1dDK8SwxRzUL5ZN3+QIdijGkklhxqoUN0M1LaRfKlM5XGku0HKC3TgN3f0FhC3S7G9WrHZxuzKSopC3Q4xphGYMmhlsakxLJs5wEKT5awKCOPiFAXgzpHBzqsBjcxtT2HT5TwTQ0TEBpjgoMlh1oakxJHcalnuoxFGXkMTY4hPCT4O2lHd29LizC3XVoy5gxhyaGW0pJa0zI8hFnL9rA1p5DRAb4rurFEhLoZ2zOOTzfs/+7uaWNM8LLkUEuhbheju7Xl802efodg72/wNiG1PXmFRaTvPFBzZWNMk2bJoQ7G9vSMWmrTIoxe7X1+dlGTNyYljrAQFx/bpSVjgp4lhzo4p0ccACO7xlSabiKYtQwP4ezuscxdv98eT2pMkLPkUAftoyJ4cHIfbh3bLdChNLoJqe3ZV3CC1ZkFgQ7FGNOALDnU0TUjkugVf+ZcUio3rlccIS6xUUvGBDlLDqZWopuHMaJrDJ+s22eXlowJYj4lBxGZICKbRSRDRO6pYn24iLzlrF8iIkkV1ieKSKGI/Np5nyIiq7xeh0XkDmfdNBHJ8lp3Yf130/jThNT27Mw/xuZsexypMcGqxuQgIm7gOWAi0Bu4SkR6V6h2I3BQVbsBTwKPVFj/BP97RjSqullVB6jqAGAwcAx416v+k+XrnUeUmtPI+N7tEIGP19qlJWOClS9nDkOBDFXdrqpFwExgcoU6k4EZzvJs4Dxx5rQWkUuAHcD6U7R/HrBNVXfVMnYTIHGREQzp3Ia56y05GBOsfEkOHYE9Xu8znbIq66hqCVAAxIhIS+Bu4P5q2p8KvFmh7DYRWSMiL4tI66o2EpGbRCRdRNJzc20q6cZ2QWp7Nu0/wo68o4EOxRjTABq6Q3oanktEhVWtFJEwYBLwH6/i54GuwABgH/DXqrZV1RdVNU1V02JjY/0Zs/HBhNT2ADZqyZgg5UtyyAI6eb1PcMqqrCMiIUAUkA8MAx4VkZ3AHcDvROQ2r+0mAitUNbu8QFWzVbVUVcuAf+K5rGVOMx2jm9EvIYpP1u0LdCjGmAbgS3JYBnQXkWTnL/2pwJwKdeYA1znLlwNfqMdZqpqkqknAU8BDqvqs13ZXUeGSkojEe729FFjn686YxjUhtT2rMwvIOnQ80KEYY/ysxuTg9CHcBswFNgKzVHW9iDwgIpOcatPx9DFkAHcBlYa7ViQiLYDxwDsVVj0qImtFZA0wFrjT570xjWpCH8+lpbl2acmYoCPBcCNTWlqapqenBzqMM9IFTy4gqnkos34+ItChGGNqSUSWq2paVevsDmlTLxektmfZzgPkHjkZ6FCMMX5kycHUy8TU9qjCpxuya65sjGkyLDmYeunZPpLOMc35xG6IMyaoWHIw9SIiTEhtz+KMPAqOFQc6HGOMn1hyMPU2oU97SsqUzzfZpSVjgoUlB1Nv/ROiiY+KsMeHGhNELDmYenO5hAv6tGfBllyOniwJdDjGGD+w5GD84oI+7TlZUsb8zTYJojHBwJKD8YuhyW2IaRFmo5aMCRKWHIxfuF3C+N7t+GJjNieKSwMdjjGmniw5GL+ZkNqeo0WlLMrIC3Qoxph6suRg/GZk17ZERoTYqCVjgoAlB+M3YSEuxvVqx2cbsykuLQt0OMaYerDkYPzqgj7tOXSsmCXbDwQ6FGNMPVhyMH51To9YmoW6+WR93Z4Qd+REMYsz8ii0+yWMCaiQQAdggkuzMDdjUmKZuz6bByal4nJJtfULjheTvvMA327PZ8mOA6zLKqBM4eL+HfjbVQMbKWpjTEWWHIzfTUhtz8fr9rNi90HSktp8b92hY0Us3XGAJTs8CWHDvsOoQpjbxYBO0dw2thvZh0/yVvoerh/ZmcGd25ziU4wxDcmn5CAiE4CnATfwkqo+XGF9OPAqMBjIB6ao6k6v9YnABmCaqj7ulO0EjgClQEn504hEpA3wFpAE7ASuVNWDdd1B0/jO7RlHmNvFx+v20yW2JUt35PPtdk9C2LTfSQYhLgYlRnP7ud0Z3iWGgYnRRIS6AThWVML8LTk88MEG3r1lVI1nH8YY/6sxOYiIG3gOz/OeM4FlIjJHVTd4VbsROKiq3URkKvAIMMVr/RPAx1U0P1ZVKw6Kvwf4XFUfFpF7nPd3+7xHJuAiI0IZ3b0tr36zk+kLdwAQEepicOfW3DmuB8OS29C/0/+SQUXNw0K4e0JP7pq1mvdWZfHDQQmNGb4xBt/OHIYCGaq6HUBEZgKT8ZwJlJsMTHOWZwPPioioqorIJcAO4KiPMU0GxjjLM4D5WHJocm46uwsuEQYmRjMsuQ39EqIJC/F9/MMlAzoyY/FOHvlkExNS29M8zK6AGtOYfPlt7Qjs8Xqf6ZRVWUdVS4ACIEZEWuL5Yr+/inYVmCciy0XkJq/ydqpaPtRlP9CuqqBE5CYRSReR9Nxcm+ztdDO8SwwvXZfGrWO7kZbUplaJATwzvd53cW+yD5/kha+2N1CUxphTaeihrNOAJ1W1sIp1o1V1EDARuFVEzq5YQVUVTxKpRFVfVNU0VU2LjY31Z8zmNDG4cxsu7t+Bf3y1jaxDxwMdjjFnFF+SQxbQyet9glNWZR0RCQGi8HRMDwMedTqf7wB+JyK3AahqlvMzB3gXz+UrgGwRiXfaigdyartTJnjcPSEFgEc/2RTgSIw5s/iSHJYB3UUkWUTCgKnAnAp15gDXOcuXA1+ox1mqmqSqScBTwEOq+qyItBCRSAARaQGcD6yroq3rgPfrtmsmGCS0bs5NZ3fh/VV7Wb7LBq0Z01hqTA5OH8JtwFxgIzBLVdeLyAMiMsmpNh1PH0MGcBeeEUbVaQcsFJHVwFLgv6r6ibPuYWC8iGwFxjnvzRns5nO6EhcZzoMfbqCsrMqrjMYYPxPPZf2mLS0tTdPT0wMdhmlA/0nfw29mr+GpKQO4ZGDF8RDGmLoQkeXl95hVZHMrmSbhskEJpHZsxcMfb+JYkc27ZExDs+RgmgSXS7jvoj7sP3yCFxfY0FZjGpolB9NkDE1uww/6xvPCV9vYV2BDW41pSJYcTJNyz8SelCk8+snmQIdiTFCz5GCalE5tmvPT0cm8uzKLlbttaKsxDcWSg2lybhnbjbYtw3ngww0Ew2g7Y05HlhxMk9MyPITfXpDCyt2HmLN6b6DDMSYoWXIwTdJlgxPo06EVj3y8ieNFpYEOx5igY8nBNElul/DHi3qzt+AE//zahrYa42+WHEyTNbxLDBNT2/P8/G3sLzgR6HCMCSqWHEyTdu/EXpSWKY/OtVlbjfEnSw6mSUuMac5PRifzzoosVu85FOhwjAkalhxMk3fr2K60bRlmQ1uN8SNLDqbJi4wI5dfnp7B810E+XLOv5g2MMTWy5GCCwhVpnegV34rfv7uW3/xnNe+syLT5l4yph5BAB2CMP7hdwtNTB/D43M3M25DNf5ZnApDctgXDu8QwomsMI7rEEBsZHuBIjWkafHrYj4hMAJ4G3MBLqvpwhfXhwKvAYDzPjp6iqju91icCG4Bpqvq4iHRy6rcDFHhRVZ926k4DfgbkOpv/TlU/qi4+e9iP8VZapmzcd5hvt+ezeFs+S3ccoPCk5xkQ3eNafpcohneJoXWLsABHa0zgVPewnxqTg4i4gS3AeCATzzOlr1LVDV51bgH6qerNIjIVuFRVp3itn40nCSxxkkM8EK+qK5xnSS8HLlHVDU5yKFTVx33dQUsOpjolpWWs23uYb7bl8832fNJ3HuCYc1d1z/aRjOzalhFdYzire1siQt0BjtaYxlNdcvDlstJQIENVtzuNzQQm4zkTKDcZmOYszwaeFRFRVRWRS4AdwNHyyqq6D9jnLB8RkY1AxwptGuMXIW4XAzpFM6BTNL8Y05Xi0jLWZB5icYYnWby+ZBcvL9pBx+hm/OaCFCb174DLJYEO25iA8qVDuiOwx+t9plNWZR1VLQEKgBgRaQncDdx/qsZFJAkYCCzxKr5NRNaIyMsi0voU290kIukikp6bm1tVFWOqFOp2MbhzG355Xnfe+Nlw1kw7n1euH0J081DueGsVk59bxOJteYEO05iAaujRStOAJ1W1sKqVTvJ4G7hDVQ87xc8DXYEBeM4u/lrVtqr6oqqmqWpabGysv+M2Z5DwEDdje8bxwW2jeeLK/uQXnuTqfy7hxn8tY2v2kUCHZ0xA+HJZKQvo5PU+wSmrqk6miIQAUXg6pocBl4vIo0A0UCYiJ1T1WREJxZMYXlfVd8obUtXs8mUR+SfwYa33ypg6cLmEHw5K4MK+8byyaCd//zKDC55awJQhidw5vjtxkRGBDtGYRuPLmcMyoLuIJItIGDAVmFOhzhzgOmf5cuAL9ThLVZNUNQl4CnjISQwCTAc2quoT3g05ndXlLgXW1XanjKmPiFA3vxjTla9+O5ZrRyTxn/Q9jHlsPk9/tpVjRSWBDs+YRlFjcnD6EG4D5gIbgVmqul5EHhCRSU616Xj6GDKAu4B7amh2FHANcK6IrHJeFzrrHhWRtSKyBhgL3Fn73TKm/tq0CGPapD58dtc5jEmJ5cnPtjDmsfnMXLqb0jKbpsMEN5/uczjd2VBW0xiW7zrIQx9tZPmug/Ro15J7J/ZiTEosnhNhY5qe6oay2vQZxvhocOfWzL55BM//aBBFJWXc8K9l/OilJazfWxDo0IzxO0sOxtSCiDCxbzzz7jyHaRf3ZuO+w1zy3CI+25Bd88bGNCGWHIypg7AQF9ePSubLX4+hd4cofvH6cj5Ztz/QYRnjN5YcjKmH6OZhvHbjUPp2jOK2N1bw0VqbMtwEB0sOxtRTq4hQXr1xGAMTo/nlmyuZs3pvoEMypt4sORjjBy3DQ/jXDUNJ69yaO2au5N2VmYEOyZh6seRgjJ+0CA/hlRuGMLxLDHfNWs3s5ZYgTNNlycEYP2oeFsL064YwultbfjN7NW8t2x3okIypE0sOxvhZszA3/7w2jbO7x3L322t5fcmuQIdkTK1ZcjCmAUSEunnx2sGc2zOO37+7jle/2RnokIypFUsOxjSQ8BA3L/x4MON7t+O+99czfeGOQIdkjM8sORjTgMJCXPz9R4OYmNqeBz/cwIsLtgU6JGN8YsnBmAYW6nbxzFUD+UG/eB76aBN/n58R6JCMqZEvD/sxxtRTqNvF01MGEOISHv1kMyWlyu3ndQ90WMackiUHYxpJiNvFE1cOwO0Snvh0CyVlyp3jutuU3+a0ZMnBmEbkdgmPXd6fEJfwzOdbWZyRx+QBHbiwbzwxLcMDHZ4x37GH/RgTAGVlyvSFO5iVvoetOYW4XcKobm25uF88F6S2p1VEaKBDNGeA6h7241NyEJEJwNOAG3hJVR+usD4ceBUYDOQDU1R1p9f6RGADME1VH6+uTRFJBmYCMcBy4BpVLaouPksOpqlSVTZnH2HOqr18sGYvew4cJyzExdiUWC7u34HzerajWZg70GGaIFWv5CAibmALMB7IBJYBV6nqBq86twD9VPVmEZkKXKqqU7zWzwYUWKKqj1fXpojMAt5R1Zki8gKwWlWfry5GSw4mGKgqq/YcYs7qvXy4Zh+5R07SIszN+N7tuLh/B87qHktYiA0wNP5TXXLwpc9hKJChqtudxmYCk/GcCZSbDExzlmcDz4qIqKqKyCXADuBoTW2KyEbgXOBqp94Mp91qk4MxwUBEGJjYmoGJrfnDD3qzZEc+H6zey0dr9/Peqr1ENQtlYmp7JvXvwLAuMbhd1pFtGo4vyaEjsMfrfSYw7FR1VLVERAqAGBE5AdyN5wzh1z60GQMcUtUSr/KOVQUlIjcBNwEkJib6sBvGNB1ulzCya1tGdm3L/ZNSWZiRy5xVe5mzei8zl+2hW1xLZt88gujmYYEO1QSphj5HnQY8qaqF/m5YVV9U1TRVTYuNjfV388acNsJCXJzbsx1PTR3I8j+M54kr+7Mr/yj/b9Zqysqa/oASc3ry5cwhC+jk9T7BKauqTqaIhABReDqmhwGXi8ijQDRQ5pxNLD9Fm/lAtIiEOGcPVX2WMWesZmFufjgogSMnSvjTnPW8sGAbt4zpFuiwTBDy5cxhGdBdRJJFJAyYCsypUGcOcJ2zfDnwhXqcpapJqpoEPAU8pKrPnqpN9fSOf+m0gdPm+3XfPWOC07UjOnNRv3gen7uZb7blBzocE4RqTA7OX/C3AXOBjcAsVV0vIg+IyCSn2nQ8fQwZwF3APXVp01l9N3CX01aM07YxxouI8PBl/Uhq24JfvrmSnMMnAh2SCTJ2E5wxTdjm/UeY/NxC+idE8/pPhxHitqGuxnfVDWW1/0nGNGEp7SN56NK+LNlxgL9+uiXQ4ZggYsnBmCbuh4MSuGpoIs/P38bnG7MDHY4JEpYcjAkCf7q4N306tOLOt1ax58CxQIdjgoAlB2OCQESom7//aBAK3PrGCk6WlAY6JNPEWXIwJkh0jmnBX6/oz5rMAv784cZAh2OaOEsOxgSR8/u056azu/Dat7t4f5XdP2rqzpKDMUHmNxekMCSpNfe+s5at2UcCHY5poiw5GBNkQt0unr16EM3D3Pzi9RUcPVlS80bGVGDJwZgg1K5VBE9PHci23EJ+/+5aguFmV9O4LDkYE6RGdWvLXeN68N6qvby+ZHegwzFNjCUHY4LYrWO7MSYllgc+2MCazEOBDsc0ITa3kjFB7uDRIn7wzNe4XMJ/f3kWUc1Dq61fXFpGzpGT7Dt0nL0FJ9h36Dj7Ck7QMjyEm87pQquI6rc3TUe9niHdFFhyMKZ6K3YfZMo/vuHs7rE89MO+7HW+8Mt/7is4zt5Dnp+5R05S8RlCkeEhHC0qITYynAcnp3J+n/aB2RHjV5YcjDH8a9EOpn2woVJ5RKiLDlHNiI+OID6qGR2iIoiPbkZ8VAQdnJ+REaGs3nOIu99ew6b9R7iwb3umTepDXGREAPbE+IslB2MMqsqc1Xs5fLyYeCcZdIhqRnTzUETEpzaKS8v4x1fbeObzDJqFufn9D3pxxeAEn7c3pxdLDsYYv8rIKeTed9awbOdBRndry0OX9iUxpnmgwzK1VO/nOYjIBBHZLCIZIlLpKW8iEi4ibznrl4hIklM+VERWOa/VInKpU57iVb5KRA6LyB3OumkikuW17sK67rgxpmF0i2vJWzeN4MFLUlm15xDnP/UV/1ywnZLSskCHZvykxjMHEXEDW4DxQCae5z9fpaobvOrcAvRT1ZtFZCpwqapOEZHmQJGqlohIPLAa6OA8JtS7/SxgmKruEpFpQKGqPu7rTtiZgzGBs6/gOH98bx2fbcyhX0IUj1zWj17xrQIdlvFBfc8chgIZqrpdVYuAmcDkCnUmAzOc5dnAeSIiqnrMKxFEAFVlovOAbaq6y4dYjDGnmfioZvzz2jT+dtVAsg4e5+K/LeSxuZs4UWzThjdlviSHjsAer/eZTlmVdZxkUADEAIjIMBFZD6wFbvY+a3BMBd6sUHabiKwRkZdFpLVPe2KMCRgR4eL+HfjsrnOYPKAjz325jQuf+ZqlOw4EOjRTRw1+h7SqLlHVPsAQ4F4R+W7sm4iEAZOA/3ht8jzQFRgA7AP+WlW7InKTiKSLSHpubm5DhW+MqYXWLcL465X9efUnQykqKePKf3zD799da5P/NUG+JIcsoJPX+wSnrMo6IhICRAH53hVUdSNQCKR6FU8EVqhqtle9bFUtVdUy4J94LmtVoqovqmqaqqbFxsb6sBvGmMZydo9Y5t15NjeOTubNpbv5f7NW2+R/TYwvyWEZ0F1Ekp2/9KcCcyrUmQNc5yxfDnyhqupsEwIgIp2BnsBOr+2uosIlJafjutylwDof98UYcxppHhbCHy/qzb0Te/HJ+v38+1vrVmxKQmqq4Iw0ug2YC7iBl1V1vYg8AKSr6hxgOvCaiGQAB/AkEIDRwD0iUgyUAbeoah6AiLTAMwLq5xU+8lERGYCn83pnFeuNMU3IjaOTWbQtjwf/u5HBndvQu4ONZGoK7CY4Y0yDyy88ycSnv6ZlRAgf3DaaFuE1/l1qGkG9b4Izxpj6iGkZzlNTB7Aj7yj3vb8+0OEYH1hyMMY0ipFd2/LLc7vz9opM3lmRGehwTA0sORhjGs3t53ZjaHIb/vDeOrbnFjbY5+zKP2pTedSTJQdjTKMJcbt4euoAwkNc3PbGSk6W+PcualXl+fnbOOex+dz87xWWIOrBkoMxplHFRzXj8Sv6s2HfYf7vo01+a7ektIzfv7eORz7ZRP+EKD7bmM3db6+lrOKTi4xPLDkYYxrdeb3a8ZNRyfxr8U7mrt9f7/YKT5Zw44x03liym1vGdOXdW0ZxxzhP/8ZfPtpoN+DVgY0nM8YExN0TU1i28wC/nb2G1I5RdIxuVqd2sg+f4IZXlrE5+wj/98O+XDU0EYBfndedg0eLmL5wB21ahHHr2G7+DD/o2ZmDMSYgwkPc/O2qgZSWKb96c2Wd+gc27T/MJc8tYlf+UaZfl/ZdYgDPZIB/urgPlwzowGNzN/P6ErtDuzYsORhjAiapbQv+cmkq6bsO8tRnW2u17ddbc7n8+W9Qhf/cPJIxKXGV6rhcwmNX9OfcnnH84b11fLhmr79CD3qWHIwxATV5QEempHXiufkZLNya59M2s9L3cMMry0ho3Yx3bx1Z7ZQcoW4Xz109iLTOrbnzrVUs2GKzOPvCkoMxJuD+NKk3XWNbcsdbq8g9cvKU9VSVJ+Zt5rez1zCiawz/uXkE8VE191U0C3Pz0nVD6BYXyc9fW86K3Qf9GX5QsuRgjAm45mEhPHv1QI6cKOauWauqHH5aVFLGXbNW88wXGUxJ68TL1w8hMiLU58+IahbKjJ8MIa5VuKcDe/8Rf+5C0LHkYIw5LfRs34r7Lu7N11vz+MeC7d9bV3CsmGtfXsK7K7P49fk9ePiyvoS6a//1FRcZwb9vHEZ4iItrpi9hz4Fj/go/6FhyMMacNq4emsgP+sbz+LzNLN/lufSz58AxLnthMSt2HeKpKQO47dzuiEidP6NTm+a8duMwTpaUcc30JdVexjqTWXIwxpw2RISHftiX+KgIbn9zJQu35nHp3xeTc/gEr944lEsGVnx8fd2ktI/k5euHkH34JNe+vJSC48V+aTeYWHIwxpxWopqF8uzVg8g+fIIfT19CRKiLd24ZyfAuMX79nMGdW/PCNYPJyDnCz2akc7zIv/M8NXWWHIwxp50BnaL58yWpjOsVx7u3jKJbXGSDfM45PWJ54soBLNt1gFvfWEGxTdT3HZ+Sg4hMEJHNIpIhIvdUsT5cRN5y1i8RkSSnfKiIrHJeq0XkUq9tdorIWmdduld5GxH5VES2Oj9b+2E/jTFNzNShibx03RBiI8Mb9HMu7t+BByen8sWmHH47e41N1OeoMTmIiBt4DpgI9AauEpHeFardCBxU1W7Ak8AjTvk6IE1VBwATgH+IiPd8TmNVdUCFx9TdA3yuqt2Bz533xhjTYH48vDO/Pr8H767M4rdvryHzoI1i8mXivaFAhqpuBxCRmcBkYINXncnANGd5NvCsiIiqeh/hCMCXlDwZGOMszwDmA3f7sJ0xxtTZrWO7cbSolBe+2sbbKzIZ3a0tU4ckMq53HOEh7kCH1+h8uazUEdjj9T7TKauyjqqWAAVADICIDBOR9cBa4GZnPXgSxTwRWS4iN3m11U5V9znL+4F2VQUlIjeJSLqIpOfm2u3wxpj6ERHuntCTr387ltvP7c723KPc+sYKhj/0OQ9+uIEt2WfWTXMNPmW3qi4B+ohIL2CGiHysqieA0aqaJSJxwKcisklVF1TYVkWkyrMNVX0ReBEgLS3NLhIaY/wioXVz7hzfg9vP687CjDxmLdvDq9/sZPrCHQxMjGbqkE78oF8HWoYH9xMPfNm7LKCT1/sEp6yqOplOn0IUkO9dQVU3ikghkAqkq2qWU54jIu/iuXy1AMgWkXhV3Sci8UBOHfbLGGPqxe0SzukRyzk9YskvPMm7K7N4a9ke7n57Lfd/sIGL+3XgyiGdGJQYXa+b8k5XvlxWWgZ0F5FkEQkDpgJzKtSZA1znLF8OfOH81Z9c3gEtIp2BnsBOEWkhIpFOeQvgfDyd1xXbug54v267Zowx/hHTMpyfntWFeXeezdu/GMnF/TrwwZq9XPb8Ys5/cgEvfb2d/MLgutNafHl8nohcCDwFuIGXVfUvIvIAnjOAOSISAbwGDAQOAFNVdbuIXINntFExUAY8oKrviUgX4F2n+RDgDVX9i/NZMcAsIBHYBVypqgeqiy8tLU3T09Orq2KMMX5VeLKE/67Zy8xle1i5+xChbmFYcgzn9IhlTEos3eJanvZnFCKyvMJo0f+tC4Znq1pyMMYE0pbsI7y9PJMvNuWwNacQgI7RzTjbuSw1qltMrWaQbSyWHIwxppFkHTrOgi25zN+cw6KMfApPlhDiEgZ3bs05KbGM6RFHr/jI0+KswpKDMcYEQHFpGct3HeSrLbl8tTmXDfsOAxAXGe7p7E6J5axusUQ1r/6sorRMKS4tc15KSWkZRaVllJQqrVuEEdWsbmcllhyMMeY0kHP4hCdRbMnl6615FBwvxiWQ2KY5paqUlCrFpZ5EUOIkguKyMqr7mv7Lpan8aFjnOsVTXXII7oG6xhhzGolrFcEVaZ24Iq0TJaVlrM4s4KvNOWzLO0qoSwh1uwhxuwhzCyFuF6FuF6Hu8nIh1OV576njKRvQKbpBYrXkYIwxARDidjG4c2sGdz495xa1KbuNMcZUYsnBGGNMJZYcjDHGVGLJwRhjTCWWHIwxxlRiycEYY0wllhyMMcZUYsnBGGNMJUExfYaI5OKZ3rsu2gJ5fgwnGNkxqp4dn5rZMapeoI5PZ1WNrWpFUCSH+hCR9FPNLWI87BhVz45PzewYVe90PD52WckYY0wllhyMMcZUYskBXgx0AE2AHaPq2fGpmR2j6p12x+eM73MwxhhTmZ05GGOMqcSSgzHGmEqCKjmIyMsikiMi6yqU9xeRb0RkrYh8ICKtnPIwEXnFKV8tImO8trnKKV8jIp+ISNvG3Rv/E5FOIvKliGwQkfUi8iuvdW1E5FMR2er8bO2Ui4g8IyIZzrEY5JR3FpEVIrLKaevmQO2Xv/jz+DjrHnXa2ejUCfwT5eupjseop/P7d1JEfu1VP0JEljq/e+tF5P5A7JM/+fP4OOvudNpZJyJvikhEo+2MqgbNCzgbGASsq1C+DDjHWf4J8KCzfCvwirMcByzHkzBDgBygrbPuUWBaoPfPD8cnHhjkLEcCW4DeXvt4j7N8D/CIs3wh8DEgwHBgiVMeBoQ7yy2BnUCHQO/jaXR8RgKLALfz+gYYE+h9DNAxigOGAH8Bfu3VlgAtneVQYAkwPND7eBodn47ADqCZ834WcH1j7UtQnTmo6gLgQBWregALnOVPgcuc5d7AF862OcAhIA3Pf1oBWjh/7bUC9jZY4I1EVfep6gpn+QiwEc9/QIDJwAxneQZwiVf5q+rxLRAtIvGqWqSqJ5064QTBWag/jw+gQAROEsXz5ZfdGPvRkOpyjFQ1R1WXAcUV2lJVLXTehjqvJj1Cxp/HxxECNBOREKA5jfg91OR/oX20Hs8/DMAVQCdneTUwSURCRCQZGAx0UtVi4BfAWjz/GL2B6Y0bcsMSkSRgIJ6/1gDaqeo+Z3k/0M5Z7gjs8do00ykrP4Ve46x/RFWbfAItV9/jo6rfAF8C+5zXXFXd2NBxN6ZaHKPq2nCLyCo8Z+qfquqSGjZpMup7fFQ1C3gc2I3n/1CBqs5rmGgrO1OSw0+AW0RkOZ5TvSKn/GU8v8zpwFPAYqBURELxJIeBQAdgDXBvI8fcYESkJfA2cIeqHq64Xj3nsDX+Baeqe1S1H9ANuE5EavwyaAr8cXxEpBvQC0jAk0DOFZGzGiDcgPDj/6FSVR2A5zgNFZFUf8caCH76P9Qazx+1yXi+h1qIyI8bINwqnRHJQVU3qer5qjoYeBPY5pSXqOqdqjpAVScD0XiuEQ5w1m9z/hFn4bmG3OQ5ie9t4HVVfcdrVbZzOQTnZ45TnsX/zrTA80uc5d2mc8awDmjyX35+PD6XAt+qaqFz6eRjYERDx98Y6nCMaqSqh/CcaU3wY6gB4cfjMw7Yoaq5ztWMd2jE76EzIjmISJzz0wX8AXjBed9cRFo4y+OBElXdgOeXu7eIlM9WOB7PtcMmzek/mQ5sVNUnKqyeA1znLF8HvO9Vfq0zKmc4nlPbfSKSICLNnHZbA6OBzQ2+Ew3In8cHz6WAc5xLlqHAOZy5/4dO1VasiEQ7y83w/J5t8mvAjcyfxwfP/6HhzveUAOfRmP+HGqvnuzFeeM4K9uHp2MkEbnTKf4XnjGAL8DD/uzM8Cc8X2kbgMzzT15a3dbNTvgb4AIgJ9P754fiMxnMquwZY5bwudNbFAJ8DW51j0cYpF+A5PGdba4E0p3y8085q5+dNgd6/0+z4uIF/OP+HNgBPBHr/AniM2ju/j4fxDPrIxDPIox+w0mlrHXBfoPfvdDo+zrr78STMdcBrOCMEG+Nl02cYY4yp5Iy4rGSMMaZ2LDkYY4ypxJKDMcaYSiw5GGOMqcSSgzHGmEosORhjjKnEkoMxxphKLDkY4yMReU9Eljvz69/klBWKyF+cZxJ8Wz6/lIj8y3mGw2IR2S4il3u18xsRWSae5z/c71X+Y+f5BqtE5B8i4m78vTTGw5KDMb77iXrm50oDbheRGKAFnjmU+uOZFv5nXvXj8dwxexGeO/MRkfOB7sBQPHN4DRaRs0WkFzAFGKWeiehKgR81xk4ZU5WQQAdgTBNyu4hc6ix3wvMlXwR86JQtxzOtSLn3VLUM2OA1Y+35zmul876l004/PFPGL/NMo0MzajFxnTH+ZsnBGB+I5xGy44ARqnpMRObjeZhPsf5vDppSvv87ddK7Ca+f/6eq/6jQ/i+BGaoaNFPDm6bNLisZ45so4KCTGHrieSRoXcwFfuLM94+IdHRmDf4cuNxrBuE2ItLZH4EbUxd25mCMbz4BbhaRjXhm8v22Lo2o6jynf+Eb5/JRIfBjVd0gIn8A5jlTyxfjecb5Lr9Eb0wt2aysxhhjKrHLSsYYYyqx5GCMMaYSSw7GGGMqseRgjDGmEksOxhhjKrHkYIwxphJLDsYYYyr5/8thGLTxF0+pAAAAAElFTkSuQmCC\n", "text/plain": ["
"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["view.plot(x=\"annee\", y=\"valeur\");"]}, {"cell_type": "markdown", "metadata": {}, "source": ["### version 2 : pyensae\n", "\n", "[import_flatfile_into_database](http://www.xavierdupre.fr/app/pyensae/helpsphinx/pyensae/sql/database_helper.html) est une fonction \u00e0 utiliser lorsqu'on ne sait pas toujours quel est le s\u00e9parateur de colonnes dans le fichier \u00e0 importer. La fonction le devine pour vous ainsi que le type de chaque colonne (quand c'est possible). L'autre aspect int\u00e9ressant est qu'elle affiche son \u00e9tat d'avancement. On rep\u00e8re plus rapidement que quelque chose se passe mal. Enfin, pour les gros fichiers, la fonction ne charge pas tout le fichier en m\u00e9moire. Cela permet de placer dans une base SQLite des milliards de lignes (cela peut prendre plus d'une heure). Ce n'est pas le cas ici, c'est juste \u00e0 titre d'exemple. On stocke l'ensemble des donn\u00e9es au format SQLite 3 de fa\u00e7on \u00e0 pouvoir les consulter plus facilement."]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": [" TextFile: opening file mortalite_5column.txt\n", " TextFile.guess_columns: processing file mortalite_5column.txt\n", " TextFile: opening file mortalite_5column.txt\n", " TextFile.guess_columns: using 101 lines\n", " TextFile: closing file mortalite_5column.txt\n", " TextFile.guess_columns: sep '\\t' nb cols 6 bestnb 101 more {('\\t', 5): 101, (' ', 1): 100}\n", " TextFile.guess_columns: header True columns {0: ('annee', ), 1: ('valeur', ), 2: ('age', ), 3: ('indicateur', ), 4: ('genre', ), 5: ('pays', )}\n", " compiling ^(?P([-]?[1-9][0-9]*?)|(0?))\\t(?P[-]?[0-9]*?([.][0-9]*?)?([eE][-]?[0-9]{0,4})?)\\t(?P.*)\\t(?P.*)\\t(?P.*)\\t(?P.*)$\n", " TextFile.guess_columns: regex ^(?P([-]?[1-9][0-9]*?)|(0?))\\t(?P[-]?[0-9]*?([.][0-9]*?)?([eE][-]?[0-9]{0,4})?)\\t(?P.*)\\t(?P.*)\\t(?P.*)\\t(?P.*)$\n", " TextFile.guess_columns: header True columns {0: ('annee', ), 1: ('valeur', ), 2: ('age', (, 6)), 3: ('indicateur', (, 18)), 4: ('genre', (, 2)), 5: ('pays', (, 4))}\n", " [_guess_columns] sep=['\\t']\n", " TextFile: closing file mortalite_5column.txt\n", " [_guess_columns] columns_name=None\n", " guess with 1001 lines\n", " count_types {0: {: 1000}, 1: {: 1000}, 2: {: 1000}, 3: {: 1000}, 4: {: 1000}, 5: {: 1000}}\n", " columns {0: ('annee', ), 1: ('valeur', ), 2: ('age', ), 3: ('indicateur', ), 4: ('genre', ), 5: ('pays', )}\n", " guess {0: ('annee', ), 1: ('valeur', ), 2: ('age', (, 6)), 3: ('indicateur', (, 18)), 4: ('genre', (, 2)), 5: ('pays', (, 20))}\n", "SQL 'CREATE TABLE mortalite_5column(annee INTEGER,'\n", "' valeur FLOAT,'\n", "' age TEXT,'\n", "' indicateur TEXT,'\n", "' genre TEXT,'\n", "' pays TEXT);'\n", " column_has_space False ['annee', 'valeur', 'age', 'indicateur', 'genre', 'pays']\n", " changes {}\n", " TextFileColumns (2): regex: {0: ('annee', ), 1: ('valeur', ), 2: ('age', (, 6)), 3: ('indicateur', (, 18)), 4: ('genre', (, 2)), 5: ('pays', (, 20))}\n", " TextFile.guess_columns: processing file mortalite_5column.txt\n", " TextFile: opening file mortalite_5column.txt\n", " TextFile.guess_columns: using 101 lines\n", " TextFile: closing file mortalite_5column.txt\n", " TextFile.guess_columns: sep '\\t' nb cols 6 bestnb 101 more {('\\t', 5): 101, (' ', 1): 100}\n", " TextFile.guess_columns: header True columns {0: ('annee', ), 1: ('valeur', ), 2: ('age', ), 3: ('indicateur', ), 4: ('genre', ), 5: ('pays', )}\n", " compiling ^(?P([-]?[1-9][0-9]*?)|(0?))\\t(?P[-]?[0-9]*?([.][0-9]*?)?([eE][-]?[0-9]{0,4})?)\\t(?P.*)\\t(?P.*)\\t(?P.*)\\t(?P.*)$\n", " TextFile.guess_columns: regex ^(?P([-]?[1-9][0-9]*?)|(0?))\\t(?P[-]?[0-9]*?([.][0-9]*?)?([eE][-]?[0-9]{0,4})?)\\t(?P.*)\\t(?P.*)\\t(?P.*)\\t(?P.*)$\n", " TextFile.guess_columns: header True columns {0: ('annee', ), 1: ('valeur', ), 2: ('age', (, 6)), 3: ('indicateur', (, 18)), 4: ('genre', (, 2)), 5: ('pays', (, 4))}\n", " TextFile: opening file mortalite_5column.txt\n", "adding 100000 lines into table mortalite_5column\n", "adding 200000 lines into table mortalite_5column\n", "adding 300000 lines into table mortalite_5column\n", "adding 400000 lines into table mortalite_5column\n", "adding 500000 lines into table mortalite_5column\n", "adding 600000 lines into table mortalite_5column\n", "adding 700000 lines into table mortalite_5column\n", "adding 800000 lines into table mortalite_5column\n", "adding 900000 lines into table mortalite_5column\n", "adding 1000000 lines into table mortalite_5column\n", "adding 1100000 lines into table mortalite_5column\n", "adding 1200000 lines into table mortalite_5column\n", "adding 1300000 lines into table mortalite_5column\n", "adding 1400000 lines into table mortalite_5column\n", "adding 1500000 lines into table mortalite_5column\n", "adding 1600000 lines into table mortalite_5column\n", "adding 1700000 lines into table mortalite_5column\n", "adding 1800000 lines into table mortalite_5column\n", "adding 1900000 lines into table mortalite_5column\n", "adding 2000000 lines into table mortalite_5column\n", "adding 2100000 lines into table mortalite_5column\n", " processing line 2124918 read bytes 67108864 sel 0 ratio 61.77 %\n", "adding 2200000 lines into table mortalite_5column\n", "adding 2300000 lines into table mortalite_5column\n", "adding 2400000 lines into table mortalite_5column\n", "adding 2500000 lines into table mortalite_5column\n", "adding 2600000 lines into table mortalite_5column\n", "adding 2700000 lines into table mortalite_5column\n", "adding 2800000 lines into table mortalite_5column\n", "adding 2900000 lines into table mortalite_5column\n", "adding 3000000 lines into table mortalite_5column\n", "adding 3100000 lines into table mortalite_5column\n", "adding 3200000 lines into table mortalite_5column\n", "^(?P([-]?[1-9][0-9]*?)|(0?))\\t(?P[-]?[0-9]*?([.][0-9]*?)?([eE][-]?[0-9]{0,4})?)\\t(?P.*)\\t(?P.*)\\t(?P.*)\\t(?P.*)$\n", "error regex 0 unable to interpret line 3254824 : ''\n", " TextFile: closing file mortalite_5column.txt\n", "3254823 lines imported\n"]}, {"data": {"text/plain": ["'mortalite_5column'"]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["from pyensae.sql import import_flatfile_into_database\n", "import_flatfile_into_database(\"mortalite.db3\", \"mortalite_5column.txt\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Ensuite, on peut facilement consulter les donn\u00e9es avec le logiciel (sous Windows) [SQLiteSpy](http://www.yunqa.de/delphi/doku.php/products/sqlitespy/index) ou l'extension [sqlite-manager](https://addons.mozilla.org/fr/firefox/addon/sqlite-manager/) pour Firefox sous toutes les plates-formes. Pour cet exercice, on ex\u00e9cute :"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
anneevaleurageindicateurgenrepays
019980.05303Y80DEATHRATETFR
119990.04811Y80DEATHRATETFR
220000.05344Y80DEATHRATETFR
320010.05016Y80DEATHRATETFR
420020.04915Y80DEATHRATETFR
520030.04946Y80DEATHRATETFR
620040.04507Y80DEATHRATETFR
720050.04542Y80DEATHRATETFR
820060.04294Y80DEATHRATETFR
920070.04258Y80DEATHRATETFR
1020080.04180Y80DEATHRATETFR
1120090.04041Y80DEATHRATETFR
1220100.03992Y80DEATHRATETFR
1320110.03807Y80DEATHRATETFR
1420120.03823Y80DEATHRATETFR
1520130.03732Y80DEATHRATETFR
1620140.03540Y80DEATHRATETFR
1720150.03663Y80DEATHRATETFR
1820160.03510Y80DEATHRATETFR
1920170.03455Y80DEATHRATETFR
2020180.03415Y80DEATHRATETFR
2120190.03418Y80DEATHRATETFR
\n", "
"], "text/plain": [" annee valeur age indicateur genre pays\n", "0 1998 0.05303 Y80 DEATHRATE T FR\n", "1 1999 0.04811 Y80 DEATHRATE T FR\n", "2 2000 0.05344 Y80 DEATHRATE T FR\n", "3 2001 0.05016 Y80 DEATHRATE T FR\n", "4 2002 0.04915 Y80 DEATHRATE T FR\n", "5 2003 0.04946 Y80 DEATHRATE T FR\n", "6 2004 0.04507 Y80 DEATHRATE T FR\n", "7 2005 0.04542 Y80 DEATHRATE T FR\n", "8 2006 0.04294 Y80 DEATHRATE T FR\n", "9 2007 0.04258 Y80 DEATHRATE T FR\n", "10 2008 0.04180 Y80 DEATHRATE T FR\n", "11 2009 0.04041 Y80 DEATHRATE T FR\n", "12 2010 0.03992 Y80 DEATHRATE T FR\n", "13 2011 0.03807 Y80 DEATHRATE T FR\n", "14 2012 0.03823 Y80 DEATHRATE T FR\n", "15 2013 0.03732 Y80 DEATHRATE T FR\n", "16 2014 0.03540 Y80 DEATHRATE T FR\n", "17 2015 0.03663 Y80 DEATHRATE T FR\n", "18 2016 0.03510 Y80 DEATHRATE T FR\n", "19 2017 0.03455 Y80 DEATHRATE T FR\n", "20 2018 0.03415 Y80 DEATHRATE T FR\n", "21 2019 0.03418 Y80 DEATHRATE T FR"]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["sql = \"\"\"SELECT * FROM mortalite_5column WHERE pays==\"FR\" \n", " AND age == \"Y80\" \n", " AND indicateur == \"DEATHRATE\"\n", " AND genre == \"T\"\n", " ORDER BY annee\"\"\"\n", "\n", "from pyensae.sql import Database\n", "db = Database(\"mortalite.db3\", LOG = lambda *l : None)\n", "db.connect()\n", "view = db.to_df(sql)\n", "view"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Visuellement, cela donne :"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}, {"data": {"image/png": "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\n", "text/plain": ["
"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["view.plot(x=\"annee\", y=\"valeur\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Cube de donn\u00e9es\n", "\n", "On utilise l'expression *cube de donn\u00e9es* pour d\u00e9signer \u00e0 tableaux \u00e0 plusieurs dimensions. On le repr\u00e9sente souvent par une liste ``coordonn\u00e9es, valeurs``. C'est souvent beaucoup de donn\u00e9es et pas forc\u00e9ment de moyen pratique de les manipuler. On utilise le module [xarray](http://xarray.pydata.org/en/stable/). [pandas](https://pandas.pydata.org/pandas-docs/stable/) propose automatiquement d'exporter les donn\u00e9es vers ce module avec [to_xarray](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_xarray.html#pandas-dataframe-to-xarray)."]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"data": {"text/plain": ["(3254823, 6)"]}, "execution_count": 16, "metadata": {}, "output_type": "execute_result"}], "source": ["import pandas \n", "df = pandas.read_csv(\"mortalite_5column.txt\", sep=\"\\t\", encoding=\"utf8\")\n", "df.shape"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
anneevaleurageindicateurgenrepays
020190.00021Y01DEATHRATEFAL
120180.00067Y01DEATHRATEFAL
\n", "
"], "text/plain": [" annee valeur age indicateur genre pays\n", "0 2019 0.00021 Y01 DEATHRATE F AL\n", "1 2018 0.00067 Y01 DEATHRATE F AL"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["df.head(n=2)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On passe du c\u00f4t\u00e9 *index* toutes les colonnes except\u00e9 *valeur*."]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"data": {"text/plain": ["['annee', 'age', 'indicateur', 'genre', 'pays']"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["cols = [_ for _ in df.columns if _ != \"valeur\"]\n", "cols"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On laisse tomber les valeurs manquantes."]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [{"data": {"text/plain": ["(3254823, 6)"]}, "execution_count": 19, "metadata": {}, "output_type": "execute_result"}], "source": ["df.shape"]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [{"data": {"text/plain": ["(3179097, 6)"]}, "execution_count": 20, "metadata": {}, "output_type": "execute_result"}], "source": ["df = df.dropna()\n", "df.shape"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On v\u00e9rifie qu'il n'y a pas de doublons car la conversion en *cube* ne fonctionne pas dans ce cas puisque deux valeurs seraient index\u00e9es avec les m\u00eames coordonn\u00e9es."]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
valeur
anneeageindicateurgenrepays
\n", "
"], "text/plain": ["Empty DataFrame\n", "Columns: [valeur]\n", "Index: []"]}, "execution_count": 21, "metadata": {}, "output_type": "execute_result"}], "source": ["dup = df.groupby(cols).count().sort_values(\"valeur\", ascending=False)\n", "dup = dup[dup.valeur > 1]\n", "dup.head(n=2)"]}, {"cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [{"data": {"text/plain": ["(0, 1)"]}, "execution_count": 22, "metadata": {}, "output_type": "execute_result"}], "source": ["dup.shape"]}, {"cell_type": "code", "execution_count": 22, "metadata": {"scrolled": false}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
valeur
anneeageindicateurgenrepays
2019Y01DEATHRATEFAL0.00021
2018Y01DEATHRATEFAL0.00067
\n", "
"], "text/plain": [" valeur\n", "annee age indicateur genre pays \n", "2019 Y01 DEATHRATE F AL 0.00021\n", "2018 Y01 DEATHRATE F AL 0.00067"]}, "execution_count": 23, "metadata": {}, "output_type": "execute_result"}], "source": ["dfi = df.set_index(cols, verify_integrity=True)\n", "dfi.head(n=2)"]}, {"cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [{"data": {"text/plain": ["pandas.core.indexes.multi.MultiIndex"]}, "execution_count": 24, "metadata": {}, "output_type": "execute_result"}], "source": ["type(dfi.index)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On v\u00e9rifie que [xarray](http://xarray.pydata.org/en/stable/) est install\u00e9."]}, {"cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": ["import xarray"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Et on convertit en cube."]}, {"cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": ["cube = xarray.Dataset.from_dataframe(dfi) # ou dfi.to_xarray()"]}, {"cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset>\n", "Dimensions:     (annee: 60, age: 84, indicateur: 7, genre: 3, pays: 56)\n", "Coordinates:\n", "  * annee       (annee) int64 1960 1961 1962 1963 1964 ... 2016 2017 2018 2019\n", "  * age         (age) object 'Y01' 'Y02' 'Y03' 'Y04' ... 'Y81' 'Y82' 'Y83' 'Y84'\n", "  * indicateur  (indicateur) object 'DEATHRATE' 'LIFEXP' ... 'TOTPYLIVED'\n", "  * genre       (genre) object 'F' 'M' 'T'\n", "  * pays        (pays) object 'AL' 'AM' 'AT' 'AZ' 'BE' ... 'TR' 'UA' 'UK' 'XK'\n", "Data variables:\n", "    valeur      (annee, age, indicateur, genre, pays) float64 nan nan ... nan
"], "text/plain": ["\n", "Dimensions: (annee: 60, age: 84, indicateur: 7, genre: 3, pays: 56)\n", "Coordinates:\n", " * annee (annee) int64 1960 1961 1962 1963 1964 ... 2016 2017 2018 2019\n", " * age (age) object 'Y01' 'Y02' 'Y03' 'Y04' ... 'Y81' 'Y82' 'Y83' 'Y84'\n", " * indicateur (indicateur) object 'DEATHRATE' 'LIFEXP' ... 'TOTPYLIVED'\n", " * genre (genre) object 'F' 'M' 'T'\n", " * pays (pays) object 'AL' 'AM' 'AT' 'AZ' 'BE' ... 'TR' 'UA' 'UK' 'XK'\n", "Data variables:\n", " valeur (annee, age, indicateur, genre, pays) float64 nan nan ... nan"]}, "execution_count": 27, "metadata": {}, "output_type": "execute_result"}], "source": ["cube"]}, {"cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
valeur
0NaN
1NaN
\n", "
"], "text/plain": [" valeur\n", "0 NaN\n", "1 NaN"]}, "execution_count": 28, "metadata": {}, "output_type": "execute_result"}], "source": ["back_to_pandas = cube.to_dataframe().reset_index(drop=True)\n", "back_to_pandas.head(n=2)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Et on prend le maximum par *indicateur* et *genre*."]}, {"cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
genreFMT
indicateur
DEATHRATE9.978600e-011.130040e+001.040580e+00
LIFEXP8.590000e+018.310000e+018.460000e+01
PROBDEATH6.657100e-017.220600e-016.844600e-01
PROBSURV1.000000e+001.000000e+001.000000e+00
PYLIVED1.000000e+051.000000e+051.000000e+05
SURVIVORS1.000000e+051.000000e+051.000000e+05
TOTPYLIVED8.583361e+068.307177e+068.456903e+06
\n", "
"], "text/plain": ["genre F M T\n", "indicateur \n", "DEATHRATE 9.978600e-01 1.130040e+00 1.040580e+00\n", "LIFEXP 8.590000e+01 8.310000e+01 8.460000e+01\n", "PROBDEATH 6.657100e-01 7.220600e-01 6.844600e-01\n", "PROBSURV 1.000000e+00 1.000000e+00 1.000000e+00\n", "PYLIVED 1.000000e+05 1.000000e+05 1.000000e+05\n", "SURVIVORS 1.000000e+05 1.000000e+05 1.000000e+05\n", "TOTPYLIVED 8.583361e+06 8.307177e+06 8.456903e+06"]}, "execution_count": 29, "metadata": {}, "output_type": "execute_result"}], "source": ["cube.max(dim=[\"age\", \"annee\", \"pays\"]).to_dataframe().reset_index().pivot(\"indicateur\", \"genre\", \"valeur\")"]}, {"cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
valeur
indicateur
DEATHRATE1.130040e+00
LIFEXP8.590000e+01
PROBDEATH7.220600e-01
PROBSURV1.000000e+00
PYLIVED1.000000e+05
SURVIVORS1.000000e+05
TOTPYLIVED8.583361e+06
\n", "
"], "text/plain": [" valeur\n", "indicateur \n", "DEATHRATE 1.130040e+00\n", "LIFEXP 8.590000e+01\n", "PROBDEATH 7.220600e-01\n", "PROBSURV 1.000000e+00\n", "PYLIVED 1.000000e+05\n", "SURVIVORS 1.000000e+05\n", "TOTPYLIVED 8.583361e+06"]}, "execution_count": 30, "metadata": {}, "output_type": "execute_result"}], "source": ["cube.to_dataframe().groupby('indicateur').max()"]}, {"cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["cannot reduce over dimensions ['indicateur']. expected either '...' to reduce over all dimensions or one or more of Frozen({'annee': 60, 'age': 84, 'genre': 3, 'pays': 56}).\n"]}], "source": ["try:\n", " cube.groupby(\"indicateur\").max().to_dataframe().head()\n", "except ValueError as e:\n", " # It used to be working in 0.12 but not in 0.13...\n", " print(e)"]}, {"cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
indicateurgenrevaleur
anneeagepays
1980Y01ALLIFEXPFNaN
AMLIFEXPFNaN
ATLIFEXPF76.1
AZLIFEXPFNaN
BELIFEXPF76.5
\n", "
"], "text/plain": [" indicateur genre valeur\n", "annee age pays \n", "1980 Y01 AL LIFEXP F NaN\n", " AM LIFEXP F NaN\n", " AT LIFEXP F 76.1\n", " AZ LIFEXP F NaN\n", " BE LIFEXP F 76.5"]}, "execution_count": 32, "metadata": {}, "output_type": "execute_result"}], "source": ["cube[\"valeur\"].sel(indicateur=\"LIFEXP\", genre=\"F\", annee=slice(1980, 1985)).to_dataframe().head()"]}, {"cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
valeur
anneeindicateurgenrepays
1960DEATHRATEFALNaN
AMNaN
ATNaN
AZNaN
BE0.15967
\n", "
"], "text/plain": [" valeur\n", "annee indicateur genre pays \n", "1960 DEATHRATE F AL NaN\n", " AM NaN\n", " AT NaN\n", " AZ NaN\n", " BE 0.15967"]}, "execution_count": 33, "metadata": {}, "output_type": "execute_result"}], "source": ["cube[\"valeur\"].max(dim=[\"age\"]).to_dataframe().head()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On ajoute une colonne avec un ratio o\u00f9 on divise par le maximum sur une classe d'\u00e2ge."]}, {"cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": ["cube[\"max_valeur\"] = cube[\"valeur\"] / cube[\"valeur\"].max(dim=[\"age\"])"]}, {"cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
valeurmax_valeur
anneeageindicateurgenrepays
1960Y01DEATHRATEFALNaNNaN
AMNaNNaN
ATNaNNaN
AZNaNNaN
BE0.001590.009958
\n", "
"], "text/plain": [" valeur max_valeur\n", "annee age indicateur genre pays \n", "1960 Y01 DEATHRATE F AL NaN NaN\n", " AM NaN NaN\n", " AT NaN NaN\n", " AZ NaN NaN\n", " BE 0.00159 0.009958"]}, "execution_count": 35, "metadata": {}, "output_type": "execute_result"}], "source": ["cube.to_dataframe().head()"]}, {"cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": []}], "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.9.5"}}, "nbformat": 4, "nbformat_minor": 2}