"], "text/plain": [" annee valeur age age_num indicateur genre pays\n", "92886 2000 5.020000e-03 Y60 60.0 DEATHRATE F FR\n", "94532 2000 4.860000e-03 Y61 61.0 DEATHRATE F FR\n", "516236 2000 2.580000e+01 Y60 60.0 LIFEXP F FR\n", "517871 2000 2.490000e+01 Y61 61.0 LIFEXP F FR\n", "938100 2000 5.010000e-03 Y60 60.0 PROBDEATH F FR\n", "939746 2000 4.850000e-03 Y61 61.0 PROBDEATH F FR\n", "1361922 2000 9.949900e-01 Y60 60.0 PROBSURV F FR\n", "1363568 2000 9.951500e-01 Y61 61.0 PROBSURV F FR\n", "1785194 2000 9.307600e+04 Y60 60.0 PYLIVED F FR\n", "1786829 2000 9.261800e+04 Y61 61.0 PYLIVED F FR\n", "2206508 2000 9.331000e+04 Y60 60.0 SURVIVORS F FR\n", "2208143 2000 9.284300e+04 Y61 61.0 SURVIVORS F FR\n", "2627855 2000 2.405594e+06 Y60 60.0 TOTPYLIVED F FR\n", "2629490 2000 2.312517e+06 Y61 61.0 TOTPYLIVED F FR"]}, "execution_count": 9, "metadata": {}, "output_type": "execute_result"}], "source": ["df[ ((df.age==\"Y60\") | (df.age==\"Y61\")) & (df.annee == 2000) & (df.pays==\"FR\") & (df.genre==\"F\")]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Donn\u00e9es trop grosses pour tenir en m\u00e9moire : SQLite\n", "\n", "On charge une grosse base de donn\u00e9es (assez petite pour que la s\u00e9ance ne soit pas trop longue)."]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"data": {"text/plain": ["(2956833, 7)"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["df.shape"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Les donn\u00e9es sont trop grosses pour tenir dans une feuille Excel et les consulter il n'y a pas d'autres moyens que d'en regarder des extraits. Que passe-t-il quand les donn\u00e9es sont encore plus grosses et qu'elles ne tiennent pas en m\u00e9moire ? Quelques solutions :\n", "\n", "* augmenter la m\u00e9moire de l'ordinateur, avec 20 Go, on peut faire beaucoup de choses,\n", "* stocker les donn\u00e9es dans un serveur SQL,\n", "* stocker les donn\u00e9es sur un syst\u00e8me distribu\u00e9 (cloud, Hadoop, ...)\n", "\n", "La seconde option n'est pas toujours simple, il faut installer un serveur SQL. Pour aller plus vite, on peut simplement utiliser [SQLite](https://www.sqlite.org/) qui est une fa\u00e7on de faire du SQL sans serveur (cela prend quelques minutes). On utilise la m\u00e9thode [to_sql](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_sql.html)."]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": ["import sqlite3\n", "from pandas.io import sql\n", "cnx = sqlite3.connect('mortalite.db3')\n", "try:\n", " df.to_sql(name='mortalite', con=cnx)\n", "except ValueError as e:\n", " if \"Table 'mortalite' already exists\" not in str(e):\n", " # seulement si l'erreur ne vient pas du fait que cela \n", " # a d\u00e9j\u00e0 \u00e9t\u00e9 fait\n", " raise e\n", "# on peut ajouter d'autres dataframe \u00e0 la table comme si elle \u00e9tait cr\u00e9\u00e9e par morceau\n", "# voir le param\u00e8tre if_exists de la fonction to_sql"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On peut maintenant r\u00e9cup\u00e9rer un morceau avec la fonction [read_sql](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_sql.html?highlight=read_sql#pandas.read_sql)."]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "
\n", " \n", "
\n", "
\n", "
index
\n", "
annee
\n", "
valeur
\n", "
age
\n", "
age_num
\n", "
indicateur
\n", "
genre
\n", "
pays
\n", "
\n", " \n", " \n", "
\n", "
0
\n", "
74015
\n", "
2016
\n", "
0.00148
\n", "
Y50
\n", "
50.0
\n", "
DEATHRATE
\n", "
F
\n", "
AL
\n", "
\n", "
\n", "
1
\n", "
74016
\n", "
2015
\n", "
0.00174
\n", "
Y50
\n", "
50.0
\n", "
DEATHRATE
\n", "
F
\n", "
AL
\n", "
\n", "
\n", "
2
\n", "
74017
\n", "
2014
\n", "
0.00196
\n", "
Y50
\n", "
50.0
\n", "
DEATHRATE
\n", "
F
\n", "
AL
\n", "
\n", "
\n", "
3
\n", "
74018
\n", "
2016
\n", "
0.00283
\n", "
Y50
\n", "
50.0
\n", "
DEATHRATE
\n", "
F
\n", "
AM
\n", "
\n", "
\n", "
4
\n", "
74019
\n", "
2015
\n", "
0.00296
\n", "
Y50
\n", "
50.0
\n", "
DEATHRATE
\n", "
F
\n", "
AM
\n", "
\n", " \n", "
\n", "
"], "text/plain": [" index annee valeur age age_num indicateur genre pays\n", "0 74015 2016 0.00148 Y50 50.0 DEATHRATE F AL\n", "1 74016 2015 0.00174 Y50 50.0 DEATHRATE F AL\n", "2 74017 2014 0.00196 Y50 50.0 DEATHRATE F AL\n", "3 74018 2016 0.00283 Y50 50.0 DEATHRATE F AM\n", "4 74019 2015 0.00296 Y50 50.0 DEATHRATE F AM"]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["import pandas\n", "example = pandas.read_sql('SELECT * FROM mortalite WHERE age_num==50 LIMIT 5', cnx)\n", "example"]}, {"cell_type": "markdown", "metadata": {}, "source": ["L'ensemble des donn\u00e9es restent sur le disque, seul le r\u00e9sultat de la requ\u00eate est charg\u00e9 en m\u00e9moire. Si on ne peut pas faire tenir les donn\u00e9es en m\u00e9moire, il faut soit en obtenir une vue partielle (un \u00e9chantillon al\u00e9atoire, un vue filtr\u00e9e), soit une vue agr\u00e9gr\u00e9e. Pour finir, il faut fermer la connexion pour laisser d'autres applications ou notebook modifier la base ou tout simplement supprimer le fichier."]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": ["cnx.close()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Sous Windows, on peut consulter la base avec le logiciel [SQLiteSpy](http://www.yunqa.de/delphi/doku.php/products/sqlitespy/index)."]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"data": {"image/png": "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\n", "text/plain": [""]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["NbImage(\"sqlite.png\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Sous Linux ou Max, on peut utiliser une extension Firefox [SQLite Manager](https://addons.mozilla.org/en-US/firefox/addon/sqlite-manager/?src). Dans ce notebook, on utilisera la commande magique [%%SQL](http://www.xavierdupre.fr/app/pyensae/helpsphinx/notebooks/pyensae_sql_magic.html) du module [pyensae](http://www.xavierdupre.fr/app/pyensae/helpsphinx/) : "]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/plain": [""]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["%load_ext pyensae\n", "%SQL_connect mortalite.db3"]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"data": {"text/plain": ["['mortalite']"]}, "execution_count": 16, "metadata": {}, "output_type": "execute_result"}], "source": ["%SQL_tables"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"data": {"text/plain": ["{0: ('index', int),\n", " 1: ('annee', int),\n", " 2: ('valeur', float),\n", " 3: ('age', str),\n", " 4: ('age_num', float),\n", " 5: ('indicateur', str),\n", " 6: ('genre', str),\n", " 7: ('pays', str)}"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["%SQL_schema mortalite"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "
\n", " \n", "
\n", "
\n", "
COUNT(*)
\n", "
\n", " \n", " \n", "
\n", "
0
\n", "
2956833
\n", "
\n", " \n", "
\n", "
"], "text/plain": [" COUNT(*)\n", "0 2956833"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["%%SQL\n", "SELECT COUNT(*) FROM mortalite"]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": ["%SQL_close"]}, {"cell_type": "markdown", "metadata": {"collapsed": true}, "source": ["## Cas 1 : filtrer pour cr\u00e9er un \u00e9chantillon al\u00e9atoire\n", "\n", "Si on ne peut pas faire tenir les donn\u00e9es en m\u00e9moire, on peut soit regarder les premi\u00e8res lignes soit prendre un \u00e9chantillon al\u00e9atoire. Deux options :\n", "\n", "* [Dataframe.sample](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sample.html)\n", "* [create_function](https://docs.python.org/3.4/library/sqlite3.html#sqlite3.Connection.create_function)\n", "\n", "La premi\u00e8re fonction est simple :"]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [{"data": {"text/plain": ["((295683, 7), (2956833, 7))"]}, "execution_count": 20, "metadata": {}, "output_type": "execute_result"}], "source": ["sample = df.sample(frac=0.1)\n", "sample.shape, df.shape"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Je ne sais pas si cela peut \u00eatre r\u00e9alis\u00e9 sans charger les donn\u00e9es en m\u00e9moire. Si les donn\u00e9es p\u00e8sent 20 Go, cette m\u00e9thode n'aboutira pas. Pourtant, on veut juste un \u00e9chantillon pour commencer \u00e0 regarder les donn\u00e9es. On utilise la seconde option avec [create_function](https://docs.python.org/3.4/library/sqlite3.html#sqlite3.Connection.create_function) et la fonction suivante :"]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": ["import random #loi uniforme\n", "def echantillon(proportion):\n", " return 1 if random.random() < proportion else 0"]}, {"cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": ["import sqlite3\n", "from pandas.io import sql\n", "cnx = sqlite3.connect('mortalite.db3')"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On d\u00e9clare la fonction \u00e0 la base de donn\u00e9es."]}, {"cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": ["cnx.create_function('echantillon', 1, echantillon)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On veut r\u00e9cup\u00e9rer environ 1% de la table ? On \u00e9crit d'abord le filtre."]}, {"cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [{"data": {"text/plain": ["(29515, 8)"]}, "execution_count": 24, "metadata": {}, "output_type": "execute_result"}], "source": ["sample = pandas.read_sql('SELECT * FROM mortalite WHERE echantillon(0.01)', cnx)\n", "sample.shape"]}, {"cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "
\n", " \n", "
\n", "
\n", "
index
\n", "
annee
\n", "
valeur
\n", "
age
\n", "
age_num
\n", "
indicateur
\n", "
genre
\n", "
pays
\n", "
\n", " \n", " \n", "
\n", "
0
\n", "
50
\n", "
1975
\n", "
0.00134
\n", "
Y01
\n", "
1.0
\n", "
DEATHRATE
\n", "
F
\n", "
AT
\n", "
\n", "
\n", "
1
\n", "
129
\n", "
2009
\n", "
0.00089
\n", "
Y01
\n", "
1.0
\n", "
DEATHRATE
\n", "
F
\n", "
BG
\n", "
\n", "
\n", "
2
\n", "
137
\n", "
2001
\n", "
0.00103
\n", "
Y01
\n", "
1.0
\n", "
DEATHRATE
\n", "
F
\n", "
BG
\n", "
\n", "
\n", "
3
\n", "
281
\n", "
2001
\n", "
0.00030
\n", "
Y01
\n", "
1.0
\n", "
DEATHRATE
\n", "
F
\n", "
CZ
\n", "
\n", "
\n", "
4
\n", "
289
\n", "
1993
\n", "
0.00051
\n", "
Y01
\n", "
1.0
\n", "
DEATHRATE
\n", "
F
\n", "
CZ
\n", "
\n", " \n", "
\n", "
"], "text/plain": [" index annee valeur age age_num indicateur genre pays\n", "0 50 1975 0.00134 Y01 1.0 DEATHRATE F AT\n", "1 129 2009 0.00089 Y01 1.0 DEATHRATE F BG\n", "2 137 2001 0.00103 Y01 1.0 DEATHRATE F BG\n", "3 281 2001 0.00030 Y01 1.0 DEATHRATE F CZ\n", "4 289 1993 0.00051 Y01 1.0 DEATHRATE F CZ"]}, "execution_count": 25, "metadata": {}, "output_type": "execute_result"}], "source": ["sample.head()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On ferme la connexion."]}, {"cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": ["cnx.close()"]}, {"cell_type": "markdown", "metadata": {"collapsed": true}, "source": ["## Pseudo Map/Reduce avec SQLite"]}, {"cell_type": "markdown", "metadata": {}, "source": ["La liste des [mots-cl\u00e9s du langage SQL utilis\u00e9s par SQLite](https://www.sqlite.org/keyword_index.html) n'est pas aussi riche que d'autres solutions de serveurs SQL. La m\u00e9diane ne semble pas en faire partie. Cependant, pour une ann\u00e9e, un genre, un \u00e2ge donn\u00e9, on voudrait calculer la m\u00e9diane de l'esp\u00e9rance de vie sur l'ensembles des pays."]}, {"cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": ["import sqlite3, pandas\n", "from pandas.io import sql\n", "cnx = sqlite3.connect('mortalite.db3')"]}, {"cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "
\n", " \n", "
\n", "
\n", "
pays
\n", "
count(*)
\n", "
\n", " \n", " \n", "
\n", "
0
\n", "
AL
\n", "
5418
\n", "
\n", "
\n", "
1
\n", "
AM
\n", "
10836
\n", "
\n", "
\n", "
2
\n", "
AT
\n", "
84882
\n", "
\n", "
\n", "
3
\n", "
AZ
\n", "
16254
\n", "
\n", "
\n", "
4
\n", "
BE
\n", "
102942
\n", "
\n", " \n", "
\n", "
"], "text/plain": [" pays count(*)\n", "0 AL 5418\n", "1 AM 10836\n", "2 AT 84882\n", "3 AZ 16254\n", "4 BE 102942"]}, "execution_count": 28, "metadata": {}, "output_type": "execute_result"}], "source": ["pays = pandas.read_sql('SELECT pays, COUNT(*) FROM mortalite GROUP BY pays', cnx)\n", "pays.head()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Il n'y a pas le m\u00eame nombre de donn\u00e9es selon les pays, il est probable que le nombre de pays pour lesquels il existe des donn\u00e9es varie selon les \u00e2ges et les ann\u00e9es."]}, {"cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": ["query = \"\"\"SELECT nb_country, COUNT(*) AS nb_rows FROM (\n", " SELECT annee,age,age_num, count(*) AS nb_country FROM mortalite \n", " WHERE indicateur==\"LIFEXP\" AND genre==\"F\"\n", " GROUP BY annee,age,age_num\n", " ) GROUP BY nb_country\"\"\"\n", "df = pandas.read_sql(query, cnx)"]}, {"cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [{"data": {"text/html": ["
"]}, "metadata": {}, "output_type": "display_data"}], "source": ["ax = df.plot(x=\"nb_country\", y=\"nb_rows\")\n", "ax.set_title(\"Nombre de donn\u00e9es par pays\");"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Soit un nombre inconstant de pays. Le fait qu'on est 100 pays sugg\u00e8re qu'on ait une erreur \u00e9galement."]}, {"cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": ["query = \"\"\"SELECT annee,age,age_num, count(*) AS nb_country FROM mortalite \n", " WHERE indicateur==\"LIFEXP\" AND genre==\"F\"\n", " GROUP BY annee,age,age_num\n", " HAVING nb_country >= 100\"\"\"\n", "df = pandas.read_sql(query, cnx)"]}, {"cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "
\n", " \n", "
\n", "
\n", "
annee
\n", "
age
\n", "
age_num
\n", "
nb_country
\n", "
\n", " \n", " \n", "
\n", "
0
\n", "
2006
\n", "
None
\n", "
None
\n", "
100
\n", "
\n", "
\n", "
1
\n", "
2007
\n", "
None
\n", "
None
\n", "
100
\n", "
\n", "
\n", "
2
\n", "
2008
\n", "
None
\n", "
None
\n", "
100
\n", "
\n", "
\n", "
3
\n", "
2009
\n", "
None
\n", "
None
\n", "
100
\n", "
\n", "
\n", "
4
\n", "
2010
\n", "
None
\n", "
None
\n", "
100
\n", "
\n", " \n", "
\n", "
"], "text/plain": [" annee age age_num nb_country\n", "0 2006 None None 100\n", "1 2007 None None 100\n", "2 2008 None None 100\n", "3 2009 None None 100\n", "4 2010 None None 100"]}, "execution_count": 33, "metadata": {}, "output_type": "execute_result"}], "source": ["df.head()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Ce sont des valeurs manquantes. Le probl\u00e8me pour calculer la m\u00e9diane pour chaque observation est qu'il faut d'abord regrouper les lignes de la table par indicateur puis choisir la m\u00e9diane dans chaque de ces petits groupes. On s'inspire pour cela de la logique Map/Reduce et de la fonction [create_aggregate](https://docs.python.org/3.4/library/sqlite3.html#sqlite3.Connection.create_aggregate)."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Cas 2 : reducer customis\u00e9 avec SQL\n", "\n", "Le reducer se pr\u00e9sente toujours sous la forme suivante :"]}, {"cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": ["class ReducerMediane:\n", " def __init__(self):\n", " # ???\n", " pass\n", " def step(self, value):\n", " # ???\n", " #\n", " pass\n", " def finalize(self):\n", " # ???\n", " # return ... //2 ]\n", " pass"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Qu'on renseigne de la sorte :"]}, {"cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": ["class ReducerMediane:\n", " def __init__(self):\n", " self.indicateur = []\n", " def step(self, value):\n", " if value >= 0:\n", " self.indicateur.append(value)\n", " def finalize(self):\n", " self.indicateur.sort()\n", " return self.indicateur[len(self.indicateur)//2]"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On le d\u00e9clare ensuite \u00e0 *sqllite3*."]}, {"cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": ["cnx.create_aggregate(\"ReducerMediane\", 1, ReducerMediane) "]}, {"cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": ["query = \"\"\"SELECT annee,age,age_num, ReducerMediane(valeur) AS mediane FROM mortalite \n", " WHERE indicateur==\"LIFEXP\" AND genre==\"F\"\n", " GROUP BY annee,age,age_num\"\"\"\n", "df = pandas.read_sql(query, cnx)"]}, {"cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "
\n", " \n", "
\n", "
\n", "
annee
\n", "
age
\n", "
age_num
\n", "
mediane
\n", "
\n", " \n", " \n", "
\n", "
0
\n", "
1960
\n", "
None
\n", "
NaN
\n", "
66.7
\n", "
\n", "
\n", "
1
\n", "
1960
\n", "
Y01
\n", "
1.0
\n", "
73.7
\n", "
\n", "
\n", "
2
\n", "
1960
\n", "
Y02
\n", "
2.0
\n", "
72.8
\n", "
\n", "
\n", "
3
\n", "
1960
\n", "
Y03
\n", "
3.0
\n", "
71.9
\n", "
\n", "
\n", "
4
\n", "
1960
\n", "
Y04
\n", "
4.0
\n", "
71.0
\n", "
\n", " \n", "
\n", "
"], "text/plain": [" annee age age_num mediane\n", "0 1960 None NaN 66.7\n", "1 1960 Y01 1.0 73.7\n", "2 1960 Y02 2.0 72.8\n", "3 1960 Y03 3.0 71.9\n", "4 1960 Y04 4.0 71.0"]}, "execution_count": 38, "metadata": {}, "output_type": "execute_result"}], "source": ["df.head()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Un reducer \u00e0 deux entr\u00e9es m\u00eame si cela n'a pas beaucoup de sens ici :"]}, {"cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [], "source": ["class ReducerMediane2:\n", " def __init__(self):\n", " self.indicateur = []\n", " def step(self, value, value2):\n", " if value >= 0:\n", " self.indicateur.append(value)\n", " if value2 >= 0:\n", " self.indicateur.append(value2)\n", " def finalize(self):\n", " self.indicateur.sort()\n", " return self.indicateur[len(self.indicateur)//2]\n", " \n", "cnx.create_aggregate(\"ReducerMediane2\", 2, ReducerMediane2)"]}, {"cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "
\n", " \n", "
\n", "
\n", "
annee
\n", "
age
\n", "
age_num
\n", "
mediane2
\n", "
\n", " \n", " \n", "
\n", "
0
\n", "
1960
\n", "
None
\n", "
NaN
\n", "
66.7
\n", "
\n", "
\n", "
1
\n", "
1960
\n", "
Y01
\n", "
1.0
\n", "
74.0
\n", "
\n", "
\n", "
2
\n", "
1960
\n", "
Y02
\n", "
2.0
\n", "
73.2
\n", "
\n", "
\n", "
3
\n", "
1960
\n", "
Y03
\n", "
3.0
\n", "
72.3
\n", "
\n", "
\n", "
4
\n", "
1960
\n", "
Y04
\n", "
4.0
\n", "
71.3
\n", "
\n", " \n", "
\n", "
"], "text/plain": [" annee age age_num mediane2\n", "0 1960 None NaN 66.7\n", "1 1960 Y01 1.0 74.0\n", "2 1960 Y02 2.0 73.2\n", "3 1960 Y03 3.0 72.3\n", "4 1960 Y04 4.0 71.3"]}, "execution_count": 40, "metadata": {}, "output_type": "execute_result"}], "source": ["query = \"\"\"SELECT annee,age,age_num, ReducerMediane2(valeur, valeur+1) AS mediane2 FROM mortalite \n", " WHERE indicateur==\"LIFEXP\" AND genre==\"F\"\n", " GROUP BY annee,age,age_num\"\"\"\n", "df = pandas.read_sql(query, cnx)\n", "df.head()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Il n'est apparemment pas possible de retourner deux r\u00e9sultats mais on peut utiliser une ruse qui consise \u00e0 les concat\u00e9ner dans une cha\u00eene de carac\u00e8res."]}, {"cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [], "source": ["class ReducerQuantile:\n", " def __init__(self):\n", " self.indicateur = []\n", " def step(self, value):\n", " if value >= 0:\n", " self.indicateur.append(value)\n", " def finalize(self):\n", " self.indicateur.sort()\n", " q1 = self.indicateur[len(self.indicateur)//4]\n", " q2 = self.indicateur[3*len(self.indicateur)//4]\n", " n = len(self.indicateur)\n", " return \"%f;%f;%s\" % (q1,q2,n)\n", " \n", "cnx.create_aggregate(\"ReducerQuantile\", 1, ReducerQuantile)"]}, {"cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", "\n", "
\n", " \n", "
\n", "
\n", "
annee
\n", "
age
\n", "
age_num
\n", "
quantiles
\n", "
\n", " \n", " \n", "
\n", "
0
\n", "
1960
\n", "
None
\n", "
NaN
\n", "
4.400000;72.800000;20
\n", "
\n", "
\n", "
1
\n", "
1960
\n", "
Y01
\n", "
1.0
\n", "
73.000000;74.000000;10
\n", "
\n", "
\n", "
2
\n", "
1960
\n", "
Y02
\n", "
2.0
\n", "
72.100000;73.200000;10
\n", "
\n", "
\n", "
3
\n", "
1960
\n", "
Y03
\n", "
3.0
\n", "
71.200000;72.300000;10
\n", "
\n", "
\n", "
4
\n", "
1960
\n", "
Y04
\n", "
4.0
\n", "
70.300000;71.300000;10
\n", "
\n", " \n", "
\n", "
"], "text/plain": [" annee age age_num quantiles\n", "0 1960 None NaN 4.400000;72.800000;20\n", "1 1960 Y01 1.0 73.000000;74.000000;10\n", "2 1960 Y02 2.0 72.100000;73.200000;10\n", "3 1960 Y03 3.0 71.200000;72.300000;10\n", "4 1960 Y04 4.0 70.300000;71.300000;10"]}, "execution_count": 42, "metadata": {}, "output_type": "execute_result"}], "source": ["query = \"\"\"SELECT annee,age,age_num, ReducerQuantile(valeur) AS quantiles FROM mortalite \n", " WHERE indicateur==\"LIFEXP\" AND genre==\"F\"\n", " GROUP BY annee,age,age_num\"\"\"\n", "df = pandas.read_sql(query, cnx)\n", "df.head()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On ferme la connexion."]}, {"cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": ["cnx.close()"]}, {"cell_type": "markdown", "metadata": {"collapsed": true}, "source": ["## Notion d'index"]}, {"cell_type": "markdown", "metadata": {}, "source": ["En SQL et pour de grandes tables, la notion d'index joue un r\u00f4le important pour acc\u00e9l\u00e9rer les op\u00e9rations de jointures (``JOIN``) ou de regroupement (``GROUP BY``). L'article [A thorough guide to SQLite database operations in Python](http://sebastianraschka.com/Articles/2014_sqlite_in_python_tutorial.html) montre comment faire les principales op\u00e9rations."]}, {"cell_type": "code", "execution_count": 43, "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.6.4"}}, "nbformat": 4, "nbformat_minor": 2}