{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Mapper, Reducers customis\u00e9s avec SQL\n", "\n", "Ce notebook propose l'utilisation de SQL avec [SQLite](https://sqlite.org/) pour manipuler les donn\u00e9es depuis un notebook (avec le module [sqlite3](https://docs.python.org/3.6/library/sqlite3.html))."]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"data": {"text/html": ["
run previous cell, wait for 2 seconds
\n", ""], "text/plain": [""]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["from jyquickhelper import add_notebook_menu\n", "add_notebook_menu()"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": ["%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "plt.style.use('ggplot')\n", "import pyensae\n", "from pyquickhelper.helpgen import NbImage"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Repr\u00e9sentation"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Le module [pandas](http://pandas.pydata.org/) manipule des tables et c'est la fa\u00e7on la plus commune de repr\u00e9senter les donn\u00e9es. Lorsque les donn\u00e9es sont multidimensionnelles, on distingue les coordonn\u00e9es des valeurs :"]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [{"data": {"image/png": "iVBORw0KGgoAAAANSUhEUgAAAmoAAAB6CAIAAACA+eiaAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAB14SURBVHhe7Z09jhw5k4b7KnsBAZIAGTrAHkCGIGAsObrAWAJkjClTMmXIkitgvME48mQuMM5gnVlzT7AXmA0mg3/BIDOYxayOKkbgAb5PTJIZ/Mn3LWZ1Tz/8y8Xff/+N/8/iUUP/Qqy8VewxsZgbtqOUhHAhzD5Vh/6FWHmr2GNiMTdsRykJ4UKYfaoO/Qux8laxx8RibtiOUhLChTD7VB36F2LlrWKPicXcsB2lJIQLYfapOvQvxMpbxR4Ti7lhO0pJCBfC7FN16F+IlbeKPSYWc8N2lJIQLoTZp+rQvxArbxV7TCzmhu0oJSFcCLNP1aF/IVbeKvaYWMwN21FKQrgQD1CvjgcLCwsLC4tVA72wG/zpExr/+3//ZTw6+hdi5a0CY//v//lfw5iF7SglOFkThNmnavQvxMpbxcTOmIvtKCU4WROE2adq9C/EylvFxM6Yi+0oJThZE4TZp2r0L8TKW8XEzpiL7SglOFkThNmnavQvxMpbxcTOmIvtKCU4WROE2adq9C/EylvFxM6Yi+0oJThZE4TZp2r0L8TKW8XEzpiL7SglOFkThNmnavQvxMpbxcTOmIvtKCU4WRPEbdnn53eQGcarP+jVOwTGSUq0oT/Dkt8/vdi2z8PDu+/k0jDQCXnqlPHz/TM/1ofXX8mle+W2hwxpk5Lb4s8Pz/3kP7z5Ri7dFjAC9MJu3I59/vXry21dYlwufxL+eIu3e3j7mVy6AnBbUqIN/Rnm/PPxybaWc1YTuiFPnSruRstGuLZ9fnmDt5syydANKbktzthyc2dYCNwNvbAbh+0zPwgWcZKrJeELcRX7TIeVhxe//kOvng7clpQwfH/lE9ziyae/qgpnArckJTyPmmQgbNpJSwk9kaeu4ttrf0cunn74WdWfSLj1s9/+pJfumCvbZ7rdlHmGbkhJoLmRVB2yT7DPyTMsBO6GXtiNo/ZZnQXLmP5mNbOx654C9Z8+U4ZbvPz4O6lwKnBHUsLyuEl6MId5H4OgM/LUUX789nS7Jxun2id+Zl/LO4E7PX12N9LDwy9fSP1H4gL7bC7cPZ4+d+xzutnM/MrqhoDxkpKK6jXAdU/JcENSwvHISZ4EjIM8dZTHs89VubZ9zgXSJiXIjn1e1Vo6nGGfjwKkgV7YjcvtM38Rd96P9ph98sR32u++x8m/6qtRuB8pqXn0JE8ChkGeOkqmereo5jfI3dvn8/c/Ynn+RlfFAdTs04VrXIlFAW+f+VdcWJ5JZ3a1PHyQN3vEequrWxQ90MMNZ7FlHXr6aV7t/LBJP21HGO+WT/b+Wfz2EmqSkpLYp7t1zKfVOT+TEMXQJJOZgAqkpEKcpHy6hidWOKjhsZOnjjJgn+WXW/lL16+/+DLfQ3qXBcGLFP2ejNw6apwrD53ndyxusQVNvkgpCR9E40hNUso9gK1Q3bFFzB/CDaGjwkO3yAZFJrmcsbZhHBkRVCMlCG+f+fDplFaLWPlrsYi9fZXGWHwXwEx1azb6O6q+ugWOqGPJg2OUbFQEKqAXduN69vnyRfAhiOhPqX4VqOmFOKYIPSR7I5FbAnuXWKF7lbfP/bSLau/edhNoA7VISUFcBT8bKav66E+NoYihySyBi6SEIk9SPl0jEysc1LGxk6eOIrTP3ANiRLGIEvAh9ZaiULRMa0hk0hPrPH2WVfb9sJn4yMUrpvSmm/lGI6Uk95KcWRqyi5FP+IFbZE0KUU433dqmallXh0cEVUgJMmSfo4u4t6/ScA7YpyCZ1jr6btkZHh6jYKPmwEX0wm5Mtc9UuKfI/mpenwv/2b93+uz2EI4ODQNGWexf5exTlrYjWQUb5ScPDqhESnJibuHIlTySHJuqM185aj800WRS4BIpIciTHJgueU3hoI6OnTx1lMw+SWQffosPxSkkArRF6qp9OwhG4/LYtU+hQLvIajZTCnVkOTPsTUtqe+wWqVXuWNQzGHE/PKJR+8xvFI2te3eIlIB4X51ln2Esw6fPaWPMV7YArqEXduNy++QjvkMr7DN4qifzxR0PzuU+17LUQ9ZzVRj1Oh13XB20w/5Vxj4H0i5UPvSfFbZ0OQJ1SElGnJOURsotmn1RMzvwhTRiDtW8NQtz4AopKZEnOTJd4prCQR0eO3nqKJ3nPH3yjW/50inHCQorQKxKhsIkQ5nM1YWFfRaCiPcq32ull5ANVQppZ4WxZqaMmVS5mpV0dnOu4XouPogwOYzdIvXGfUDBUdfifnhEAFwnJcieYcQMuWnhd4t8X11un/s7iuvN05vhoTF2NyoBLqEXduMc+8xkMdkP1aDkiPT7qqSDUe5Z+2ycY1JuvnlqWxge0r9a2+dI2rGkGHu7hwqoQ0oScZh558zUAfGOWWGouXMopJNJgQukpGAgyZHpktYUDur42MlTR2mrXiYouehnchCJT3shXrkLel1gVSnPoVL8ssMGnIvwKdU1ubYF0pwrUsOy51qFD9+CmahayquS47cD4DIpQdobyUX0qs6EJ88ICUj3VWvD1FPNzA8HmyTTm6fq8/IxtnsIwCX0wm7Mts9Czhz16S0QNasyLUa2kjKy9tmI0DzpdYg8me7VKv+RtHmVT8eaS+wznY0akTtBdcd6PsWTWQIXSEnOUJID0yWtKRzU8bGTp46SqR4RhYL02IfI1achc1krb7pJuBtRqWFD47JP90UkrWmkFBuGmjEl7mOBQ5pzRavnWoUP3yJfPn8XRuKrybzgdgfsk2yJzoTX/i3dVxPsc39Hcb152jN8fIzVRqXAJfTCblxun8yJLecx7bPQ1qpykU/zqlb73Bs7RH/4PtIk7HVYDiECV0hJxmCS17dPbH587OSpowjt01HJbhSgfZnzYrEn3KF5zz5Tn0w8gn2SISdaPY/bZ/MWQOptG1HsKlngsH32biexz9ZMelrTcsw+seZF9incUWafLAL7rFwkiqPUPndyyIkKy7aqr7btU5D2efaZ7tWJNMBsXCmKk9+hyQSgASlJDCY5MF3SmsJBHR87eeooA/aJZJ/Tgzo0JCDJCrXPvsJyGoewEkYsZCuUqlLykoZOSXOuaPVcD+HwLRyFc8RRZ/M2IO4CoBkpQYbts5rwZGM71lLtq1ZNiX2KdxRf09Ge4eNjvAP7ZLzKkXrOm7D2mQrp67Wtk1xD2VZbYf8qk/9A2qfZZ7eHaAbhasytWoIM4WRSoDYpiYwlCcy3T+Ggjo+dPHUUkX06OWDFBQuTKGQqkPVcS1WSj6xyVIpKjyKc9Gd3T1ojViXm0wDg8vH/lOZcwTbMC+OUHr7FRprn509DP/lSdgzjwO2gDSlBsjT6rtye8BBx0aX7qqjJzWqakLbV7e2orEMyRfV2PTLG+7PPJIJ85D1TV5P0EFQvKXUZvv/+VS5/edpyP2gAdUjJRsyZn/zYP943LRaNIgHRZFLgEikJDCYJyKfrQE0uhquVwCXy1FHyR7qK8OimT9NlBGnIZY6LpObdmlEpBPbJR9IauSo1UxKNrqVujtnT0qDwiS0KU2Qm84LbQQVSgojtc29aeBtjI01gdxtDCOyTj2w26nnGbkdnmB/jHdpnfrWKwiZb9pmrcBVB9XiDlF3l85emLVf5BlCHlADp7mW3iWQGuDqdWcrPW4LJpMAlUuI5kOTAdI1MrHBQx8ZOnjrKBfaZHuy+WJQWmH0wpxE7bNtndokLJiWBKjVSShonyZmDEVzX7QfMLan/8Vs46JyUk8ZO5uHbQQVSgsjts7uI+Zxcvq/if4ugbZ/iHcXVbNrngTHepX1uVAbGCG7TPjdqC2RewWVR5ty92s5fkPY59ilonnLzdTp+D1H2szeZJXCZlHgOJHmSfW4IBzU8dvLUVfQ+fadHl7psKZGFBPAvzUrqm+4dmHKIqkKdUJISHlWl/gAdOzm3KGTUJxNyqybn4C1IQ9JtezKP3A4qkRJkxD43qruXK+UY3FeSqeZnI97IB7ujNopbhOkamOGdMabyx7ZP4yrMWYhoNoUZZF/4NT/Z7AOtSck6wNjJU3cKDQkw7g9YZFJyIrav2sCsoBd2w+xTNVMWonUmi0fS9gFxH2hOStYBxk6eulMwmVsGWGRSciK2r9rArKAXdsPsUzVTFiLaZ/GqU/z6vQ+0JyXrAGMnT90pmMwtAywyKTkR21dtYFbQC7th9qmaOQtBv9wt4pKjJwA9kJJ1gLGTp+4UTOaWARaZlJyI7as2MCvohd0w+1TNxIVIZ9AY9c86jQPdkJJ1gLGTp+4UTOaWARaZlJyI7as2MCvohd0w+1SN/oVYeavA2MlTZxiXYDtKCU7WBGH2qRr9C7HyVjGxM+ZiO0oJTtYEYfapGv0LsfJWMbEz5mI7SglO1gTx8DcX0NjCwsLCwmLNQC/shp0+VaN/IVbeKjB28qHVMC7BdpQSnKwJwuxTNfoXYuWtYmJnzMV2lBKcrAnC7FM1+hdi5a1iYmfMxXaUEpysCcLsUzX6F2LlrWJiZ8zFdpQSnKwJwuxTNfoXYuWtYmJnzMV2lBKcrAnC7FM1+hdi5a1iYmfMxXaUEpysCcLsUzX6F2LlrWJiZ8zFdpQSnKwJwuxTNfoXYuWtYmJnzMV2lBKcrAnC7FM1+hdi5a1iYmfMxXaUEpysCcLsUzX6F2LlrWJiZ8zFdpQSnKwJ4mr2+fkddOri1R/0kjLwr2Ne9EekZwF5kBIJ9G+Tvf1MKgR+//QCq/h4951U2AdakZJhvr/abt6ecPr3ShtbqPqzpo3hTBi1B9qSp84QgX8q6/n7H9WltbmnHfXnh+fbKoe4qT+LBvmiF3bjWvaJEunisFr98/GJa980g0nctH02/zJ2ZTmNmqN/PRuakJIR4ocqCH7CmT9T6oJWxr1RB/mbppNG7YGG5Kkz9vj22s+4C7NPCkwKKblJfvz21K8wjV++kJpagVzRC7txJfvcRPDJp4+biR71vyvZpyZguKRkh80eig8o4YNL6RDBtzJ3CUY19rkBGpASIdHw3n33x0HuvkzyTObRFPMxZv2HavNG7YFm5KkzOsTjyOuvP98/g/81+6TApJCSm2R7u/D6Ky1x8eZbKlQMZIpe2I2r2KdXN6dZXr+OSBVg9nkMdIh83tCWyJE0vNUcmWGoTkpkbPfCGzXtk8kcCGaZfNEPhxw0w3CSp84btQcakafOaLNZJqqn2SfPHe+o8OHpNg6gkCh6YTeuYZ/e9ryKeUEsT0I5+ds8iCCp4RRSRtRB36r1frIhlyGqZOretpJNncNhhbSifR5+QU2ArkjJAeqPHa1VwJrUh3pAdVIyTss+cTNUk9nwxYZ9xuYTR+2BRuSpWxT+u0zvkeUppLhk9kmBSSEl6hhe6wA2NPscoxRHXumySzQ2G5tln3w/5OTRss9X73KPjE3CYYjG+GmmBrohJeNUZlP5SoL/wNEDapOSccodkmjZZ/2BgKtJd9rMUXugDXnqluXLGzeD+as5PG3wL+vMPnlgUkiJQgbXOuDt80Z+gAgyRS/sxvn26bUpqZhXuqZWFq7jFDCJWn2KCvi2lfzx9lncGvss2ta9hdyYswteKkQ5GCqj1INAJ6RkEPSM8vOKz7legpg5d6kB1CYl47TsE5NvnhfpVtliG2l4SVAv4pxRe6ANeeoWBn8mCM8f+MMjLYM0++SBSSElKhlaa8Sb7tMPP0m5TiBV9MJunG6fXulyBURpK10QBZE9lQYm2CdDrap1b76E0XGv2q1yLtUxoA9SIgCzjdGw/DlGArVJyTgt+0yvypljJQSd3vBZYYtTR+2BNuSpW5nsyy18ldfWSrNPHpgUUqKTkbXeuKk3twDkil7YjbPtk9MslL/cn5rnjJxz7LPW7rq3Rv+ZvvOhwz5dCE+fvUs8UJuUjNO0T34sMcrpxe2Rx2mj9kAb8tStDSopRu81ndknD0wKKdGKfK2B8rR6C0C26IXdONk+vVPSMyWaZXakqEsYZtkn53m5dNa9NfoPaTfjceyzBCchX4W2Wyg7fW7QSYbPWNVOCHXqktTtzFF7oA156lYn/cJf3xrNPnlgUkiJXqRrjd55K69tPZAwemE3zrVP8eEMxe50+4xeQiOXzmH7vPw7zhbQOSk5hM8/5kn+mVHP2B5Qm5SM46dxwL38vorvKlobA7cfls8ctQfakKdudfAdnYvuUcPskwcmhZToRbTW4b+S0f+pIn1AyuiF3TjVPlGw2hEVc4p9VvpbySLqaXEarrXb9yaxT6rj04HOSckhcHpDnuSfCZxh+ragB1QnJeOM2idZbtxmzOYpviaYOWoPNCJP3dqEd3Rvdr/oMvvkgUkhJVqRrPWteicAWaMXduNE++yqEkoePUB0JWzPPisBpV+yooCW1Wrtrs2yLkEOK68Q6JuUHILOTyPtpsF0gPqkZJwx+6ySb6w+UG6AiaP2QCvy1K1M9vsM4Yuxpm6affLApJASnQjW+oa9E4DE0Qu7cZ597qgS1bL4WjV3Ryd/mapSO0yEt8TpUiiBiIWYUnYLVN7D9pl6IKJMMj8KdExK+myjJnmGUefl3GzXcygBGpCScdr2+f0V91mHVg6Zlz3UY5w3ag80I0/duuA3YeEUEr4Ya7zWM/vkgUkhJRrZX+vb9k4Ackcv7MZp9olS1baQqgIaKo28h+h2Pjg/yOPtr5vaZtXQgOuo75Lracc+hX0eBHohJX2yDw0kaDKN2ebOcF2gCSkR0k412Zs0SXb1MYpVmzVqDzQkT92q4BEkN8v6P9KGRxY2blZn5wIzQUr0sb/W4Z+NuIW1hjTRC7txln2iTmUf8yu44ynVwcqB8gr0LVxurr6hv0Vpe4XbuWqbjuc3GrRPRzwVhaC5HQR6IiX71F7SWgVS81DO0I6UCJHYJzOx7R1Vd8i/+Zgxag+0Jk/dmqBc0t9eQJ2NP3Jp9rkLzAQp0YZkrc0+L7VPYwr6F2LlrQJjJ0+dYVyC7SglOFkThNmnavQvxMpbxcTOmIvtKCU4WROE2adq9C/EylvFxM6Yi+0oJThZE4TZp2r0L8TKW8XEzpiL7SglOFkThNmnavQvxMpbxcTOmIvtKCU4WROE2adq9C/EylvFxM6Yi+0oJThZE4TZp2r0L8TKW8XEzpiL7SglOFkThNmnavQvxMpbxcTOmIvtKCU4WRPEw99cQGMLCwsLC4s1A72wG3b6VI3+hVh5q8DYyYdWw7gE21FKcLImCLNP1ehfiJW3iomdMRfbUUpwsiYIs0/V6F+IlbeKiZ0xF9tRSnCyJgizT9XoX4iVt4qJnTEX21FKcLImCLNP1ehfiJW3iomdMRfbUUpwsiYIs0/V6F+IlbeKiZ0xF9tRSnCyJgizT9XoX4iVt4qJnTEX21FKcLImCLNP1ehfiJW3iomdMRfbUUpwsiYIs0/V6F+IlbeKiZ0xF9tRSnCyJgizT9XoX4iVt4qJnTEX21FKcLImiCP2+cdbuM7Gk09/0cpX4q9fXz5uAucAQyIlEugCvf1MKvz7f79/eoEXSbz8+HtVuQc0ISXDfH+13bm9dri4MV79QSp4hNWqsb/7TipIgbbkqTP6fHnjpzzEm2+kwuLAlJCSe+DrL361Hx5++UIuaQVyRS/shtnn4/DPxycuX8bYCqAKKdmBWkgM4iVK7PPzO39XF/zaNTYbrSys1pqf0VF7oCF56owmP3576ueaxs1I6hWA6SAlt8+3136dXZh9Bqk6/JndAE61z2Jp8GxHHALt8/JFhE5IiRCcAZeDT4azTyb54Lgvfv1ntBpXGHz3yAcvaEaeOqPJZp+vv2Yl4VDy9MPPVLg297ej/PuG1x/8hyezT7PPGZxlnxzoEMW9Ht0+twQwpaZ9cpmnE2RMXlgtuGzjIL63FjXQiDx1xhD4Ltde4QbubUf5T0iwvvjuwexTap/+k/4mVcUbM/ZjfpAwH4yQlRWYu2e3y4hHHBLhmHJBkswbP1lv4ahUBs3cAxdIyQE4q8axPJ595vhk6jnHw2KVJCZfLuJuNdy31aqF+SnOqSKgEXnqFgXPkc/f/8jLf75/5kqLE2fJnx+euxpmnwGYDFKijoG19q9tN8s0+4wM2ec7fzIoggglyl8ehcYVVpRF4QeZdSHU7fIolVeQJO95fA47vV3bPqmL5IW3aZ/kA4GwWnvIuMH4JegAbchTtyz1OVJgjai59vI2ArNBShQiXGtfDRfX7DOC78qqKIUJRc1F+lwfCrNP+vXZCPrPtJ4Tx2CoWaGvlikgulTlW+yXYRDdJLe2hb5j2oXminvjRs0CVUjJIOEzRHn3VF7EsH8A0IyUjNOyT0yyeV4sfXGvml+I+i5xO3GXukAb8tQtDP6ECJ4/UC7JGSUHvfPh2W9/0kvrAvNBSlQiWGt/SI2La/YZGbNP4hDoakmpW6/UkK0+c9X3kzr3t+t3W8u0NEmOWo4HejvTPkMaIbi5Ze3TRXMhGkATUjJOyz7TTiu2Fs5nmj1ZtXq9AmafM8AjiJPI1rEy/yFMF3buJMCckBKd7K21L8wM1ewz4tWqNMuallr58sxLgsyxHUZl5CPZD+12xD4FSTJc1Ns17dMFPX3WxFZ1/j2gASkZp2mf/Fhi0NVvxK599i71gDbkqVubcKD0wRwrqX26sNNnBswHKdFKb629uRaGavYZmWyfxCMLR2kekjDa9lmf+dCxilsPJAlwXp63HejtTPssid8cix106AAK9UnJOB37BOgegPS42dut1lodO33OA1USovPaNhArm4MGYDJIiV5aa+3LyZqafUam2+dGIX+hcyzcuxdQd0v11EfpDeIkownRyNsODPl69unwCexPI3dk3wHqk5Jx/EoNuJcwz7JaexJwces9uQO0IU/d6oRf5YTo/MBtRvkt2vLAVJASvTTWOrzX7YX+5YYk0Qu7occ+Ed95PCqJBZ126/3p5YvNpTBayewnSbLaqEV/YMjXtU/8JDHoNyJmZDhqn615JpBqzUnAtdg/nVOgEXnq1iZ44RsvrJKjRutb0kWBqSAlWmmutdnnY9onqSCWNtKt18rOXTzCJFF5yyHXoi/szaHx9BlO2HsrWwD1Sck4Y/Yp3BJ1tUbDpq3uAq3IU7cy2e8zhC/Ger+14rHTZwFMBSnRyfBa28vbyFT7dOKVK1elcSj9VPXcV5u1dfUNr2YgSRfJ7UJWTA67vW1UX82yQA1S0mdbGtJnSJ4Mhzj3wFekBdCClIzjM6znzc0S95GlqiysFseYjR3fK+wtBAs0I0/duhB9DF+MRV/cBJeoZ/zxk5tR1bOBuSAlGtlbawazz0hQHCYyFRt0pjIKNYy/gUAj77yyqEar8pAhNryBHAS9pcIYvHzDBVLSp700eVb8nG/Bp9EB2pASIZ1dFO0NP0tVQT4VCasN1ZQADclTtypohLmAZr/b4P6J5xUmBD9ktAwwHaREH/trzWD2GZlqn7EkRt0EqBSfHpKqbps/7FMfbWWGVzioa7LNQ952pDcgz7Bx5oMrpGSfeuDcK+LaSA5bCCkRIrFPZt25sYirbZD5GTxt50Br8tStCaon/QFa1Nn0vWY4pqTYf7u7FjAlpEQb0rUmmH3eFN6xKksI0nnMKq4PpEpKtKE/w/OAsZOnzjAuwXaUEpysCeJO7dOfFJmDBR5TzD5noT/D84Cxk6fOMC7BdpQSnKwJ4q7ts3qPGt5Y1u9XlQK5khJt6M/wPGDs5KkzjEuwHaUEJ2uCuFP77P10zJFfUXgsIFtSog39GZ4HjJ08dYZxCbajlOBkTRD3ap8b9Y/LXvBzIo8CpExKtKE/w/OAsZOnzjAuwXaUEpysCeKu7fP20b8QK28VEztjLrajlOBkTRBmn6rRvxArbxUTO2MutqOU4GRNEGafqlG+EP/x638a5MEzjMOYfSpBap9/cwGNLSx2gxjJmuBcWFhY3FGgF3aD91i4gP/P4lFD+UJ4/8B/rBeLD99iepjwKgnhQph9qg6zT81h9mkxN0x4lYTZ5z2E2afmMPu0mBsmvErC7PMewuxTc5h9WswNE14lYfZ5D2H2qTnMPi3mhgmvkjD7vIcw+9QcZp8Wc8OEV0mYfd5DmH1qDrNPi7lhwqskzD7vIcw+NYfZp8XcMOFVEqKF+Pff/wdIN1XiuDSplgAAAABJRU5ErkJggg==\n", "text/plain": [""]}, "execution_count": 4, "metadata": {}, "output_type": "execute_result"}], "source": ["NbImage(\"cube1.png\")"]}, {"cell_type": "markdown", "metadata": {"collapsed": true}, "source": ["Dans cet exemple, il y a :\n", " \n", "* 3 coordonn\u00e9es : Age, Profession, Ann\u00e9ee\n", "* 2 valeurs : Esp\u00e9rance de vie, Population\n", "\n", "On peut repr\u00e9senter les donn\u00e9s \u00e9galement comme ceci :"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"data": {"image/png": "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\n", "text/plain": [""]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["NbImage(\"cube2.png\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["C'est assez simple. Prenons un exemple : [table de mortalit\u00e9 de 1960 \u00e0 2010](http://www.data-publica.com/opendata/7098--population-et-conditions-sociales-table-de-mortalite-de-1960-a-2010) qu'on r\u00e9cup\u00e8re \u00e0 l'aide de la fonction [table_mortalite_euro_stat](http://www.xavierdupre.fr/app/actuariat_python/helpsphinx/actuariat_python/data/population.html#actuariat_python.data.population.table_mortalite_euro_stat). C'est assez long (4-5 minutes) sur l'ensemble des donn\u00e9es car elles doivent \u00eatre pr\u00e9trait\u00e9es (voir la documentation de la fonction). Pour \u00e9couter, il faut utiliser le param\u00e8tre *stop_at*."]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"data": {"text/plain": ["'mortalite.txt'"]}, "execution_count": 6, "metadata": {}, "output_type": "execute_result"}], "source": ["from sparkouille.datasets import table_mortalite_euro_stat \n", "table_mortalite_euro_stat()"]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"data": {"text/plain": ["os.stat_result(st_mode=33206, st_ino=33776997205344496, st_dev=1182297439, st_nlink=1, st_uid=0, st_gid=0, st_size=112417907, st_atime=1523378271, st_mtime=1523378288, st_ctime=1523378271)"]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}], "source": ["import os\n", "os.stat(\"mortalite.txt\")"]}, {"cell_type": "code", "execution_count": 7, "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", "
anneevaleurageage_numindicateurgenrepays
020160.00044Y011.0DEATHRATEFAL
120150.00043Y011.0DEATHRATEFAL
220140.00043Y011.0DEATHRATEFAL
320160.00035Y011.0DEATHRATEFAM
420150.00035Y011.0DEATHRATEFAM
\n", "
"], "text/plain": [" annee valeur age age_num indicateur genre pays\n", "0 2016 0.00044 Y01 1.0 DEATHRATE F AL\n", "1 2015 0.00043 Y01 1.0 DEATHRATE F AL\n", "2 2014 0.00043 Y01 1.0 DEATHRATE F AL\n", "3 2016 0.00035 Y01 1.0 DEATHRATE F AM\n", "4 2015 0.00035 Y01 1.0 DEATHRATE F AM"]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["import pandas\n", "df = pandas.read_csv(\"mortalite.txt\", sep=\"\\t\", encoding=\"utf8\", low_memory=False)\n", "df.head()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Les indicateurs pour deux \u00e2ges diff\u00e9rents :"]}, {"cell_type": "code", "execution_count": 8, "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", "
anneevaleurageage_numindicateurgenrepays
9288620005.020000e-03Y6060.0DEATHRATEFFR
9453220004.860000e-03Y6161.0DEATHRATEFFR
51623620002.580000e+01Y6060.0LIFEXPFFR
51787120002.490000e+01Y6161.0LIFEXPFFR
93810020005.010000e-03Y6060.0PROBDEATHFFR
93974620004.850000e-03Y6161.0PROBDEATHFFR
136192220009.949900e-01Y6060.0PROBSURVFFR
136356820009.951500e-01Y6161.0PROBSURVFFR
178519420009.307600e+04Y6060.0PYLIVEDFFR
178682920009.261800e+04Y6161.0PYLIVEDFFR
220650820009.331000e+04Y6060.0SURVIVORSFFR
220814320009.284300e+04Y6161.0SURVIVORSFFR
262785520002.405594e+06Y6060.0TOTPYLIVEDFFR
262949020002.312517e+06Y6161.0TOTPYLIVEDFFR
\n", "
"], "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
indexanneevaleurageage_numindicateurgenrepays
07401520160.00148Y5050.0DEATHRATEFAL
17401620150.00174Y5050.0DEATHRATEFAL
27401720140.00196Y5050.0DEATHRATEFAL
37401820160.00283Y5050.0DEATHRATEFAM
47401920150.00296Y5050.0DEATHRATEFAM
\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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
COUNT(*)
02956833
\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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
indexanneevaleurageage_numindicateurgenrepays
05019750.00134Y011.0DEATHRATEFAT
112920090.00089Y011.0DEATHRATEFBG
213720010.00103Y011.0DEATHRATEFBG
328120010.00030Y011.0DEATHRATEFCZ
428919930.00051Y011.0DEATHRATEFCZ
\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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
payscount(*)
0AL5418
1AM10836
2AT84882
3AZ16254
4BE102942
\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": ["
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
nb_countrynb_rows
401007
39982
\n", "
"], "text/plain": [" nb_country nb_rows\n", "40 100 7\n", "39 98 2"]}, "execution_count": 30, "metadata": {}, "output_type": "execute_result"}], "source": ["df.sort_values(\"nb_country\", ascending=False).head(n=2)"]}, {"cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [{"data": {"image/png": "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P/HEE9x111387//+L6+99ho//vGPefTRR/ne976XcjuNgIzoTyDuvfdeAoEAv/zlL8O2V1VV0dTUFBYdeb1e3n33XaqqqtJy7s2bN+u/Hz9+nA8//JCzzjor5nuqq6upr69n/PjxA/4VFBREfE9VVRWNjY1hkXlTU1NY1tG0adMAVRz6H3fcuHFR21NVVcU///nPsG39/66qquKdd94JE5f333+f1tbWtPWlhtY/FRUVA65D+7ZQXV3Njh07GDdu3IB9HA6HfqxTTjmFb3/72/z3f/83Tz31FM8++yxtbW0xzx/6mfp8Purq6vTPdNOmTUydOpVFixYxbdo0JkyYwCeffDKo6w09H8A777yjn6+urg6Px8PKlSuZPXs2Z5xxhv7NJ5SLL76YsWPH8vjjj/Pb3/5Wj+ZDOeecc1i0aBF///vf+c53vsPjjz8+qHYbASn0JxCFhYX87Gc/Y/ny5WHbL774YmbMmMG1117LP//5T3bt2sU3v/lNuru7ue222wZ9XkVR+M///E82bdrEzp07+eY3v0l+fj7XXnttzPf99Kc/5aWXXmLhwoVs376djz/+mH/84x985zvfwePxRHzP/PnzmTx5Mtdffz3vvvsu27dv57rrrgubtDV+/Hhuuukmvvvd7/Lb3/6Wjz76iPfff5+nn356wEMwlIULF/LOO+9w3333sXfvXl588cUBffn973+ftrY2brzxRnbt2sVbb73FDTfcwAUXXMCFF16YRK/F5/vf/z5+v58rrriCN998k08++YS33nqL++67j7fffhuAH/7wh+zevVvvjwMHDvDGG29w1113sX//fv04r7zyCh9//DH19fW88MILuv0Ri2XLlvHKK6+we/dubrvtNo4dO6bfL2eccQY7d+7kpZde4uOPP+bhhx/mhRdeGNT1vvzyyzz66KPs27ePRx55hD/+8Y/6HJEJEyagKArLly/nwIEDrFu3jp/+9KcDjqEoCrfccgs//elP6enp4ZprrtFf++ijj7jnnnt46623OHjwIO+88w5vvvlmmKUpiULmhgckoYOxGn6/X5x77rlhg7FCCPHZZ5+Jq666ShQXF4u8vDwxZ84cUVdXp7+uDcAdOnRI3/bmm28KQBw4cEDfpg0Y7tu3TwihDiqazWbx6quvijPPPFNYrVZRXV0ddmxtn0hs2rRJzJ8/XxQUFAi73S7O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\n", "text/plain": ["
"]}, "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
anneeageage_numnb_country
02006NoneNone100
12007NoneNone100
22008NoneNone100
32009NoneNone100
42010NoneNone100
\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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
anneeageage_nummediane
01960NoneNaN66.7
11960Y011.073.7
21960Y022.072.8
31960Y033.071.9
41960Y044.071.0
\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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
anneeageage_nummediane2
01960NoneNaN66.7
11960Y011.074.0
21960Y022.073.2
31960Y033.072.3
41960Y044.071.3
\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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
anneeageage_numquantiles
01960NoneNaN4.400000;72.800000;20
11960Y011.073.000000;74.000000;10
21960Y022.072.100000;73.200000;10
31960Y033.071.200000;72.300000;10
41960Y044.070.300000;71.300000;10
\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}