{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# 1A.data - DataFrame et Matrice (correction)\n", "\n", "Correction."]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"data": {"text/html": ["
\n", ""], "text/plain": [""]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["from jyquickhelper import add_notebook_menu\n", "add_notebook_menu()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Exercice 1 : cr\u00e9er un fichier Excel\n", " \n", "On souhaite r\u00e9cup\u00e9rer les donn\u00e9es [donnees_enquete_2003_television.txt](http://www.xavierdupre.fr/enseignement/complements/donnees_enquete_2003_television.txt) (source : [INSEE](http://www.insee.fr/fr/themes/detail.asp?ref_id=fd-hdv03&page=fichiers_detail/HDV03/telechargement.htm)).\n", "\n", "* ``POIDSLOG`` : Pond\u00e9ration individuelle relative\n", "* ``POIDSF`` : Variable de pond\u00e9ration individuelle\n", "* ``cLT1FREQ`` : Nombre d'heures en moyenne pass\u00e9es \u00e0 regarder la t\u00e9l\u00e9vision \n", "* ``cLT2FREQ`` : Unit\u00e9 de temps utilis\u00e9e pour compter le nombre d'heures pass\u00e9es \u00e0 regarder la t\u00e9l\u00e9vision, cette unit\u00e9 est repr\u00e9sent\u00e9e par les quatre valeurs suivantes\n", " * 0 : non concern\u00e9\n", " * 1 : jour\n", " * 2 : semaine\n", " * 3 : mois \n", " \n", "Ensuite, on veut :\n", "\n", "1. Supprimer les colonnes vides\n", "2. Obtenir les valeurs distinctes pour la colonne ``cLT2FREQ``\n", "3. Modifier la matrice pour enlever les lignes pour lesquelles l'unit\u00e9 de temps (cLT2FREQ) n'est pas renseign\u00e9e ou \u00e9gale \u00e0 z\u00e9ro.\n", "4. Sauver le r\u00e9sultat au format Excel.\n", "\n", "Vous aurez peut-\u00eatre besoin des fonctions suivantes :\n", "\n", "* [numpy.isnan](http://docs.scipy.org/doc/numpy/reference/generated/numpy.isnan.html)\n", "* [DataFrame.apply](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.apply.html)\n", "* [DataFrame.fillna](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html) ou \n", "[DataFrame.isnull](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.isnull.html)\n", "* [DataFrame.copy](http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.copy.html)"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [{"data": {"text/html": ["\n", "
\n", " \n", " \n", " | \n", " POIDLOG | \n", " POIDSF | \n", " cLT1FREQ | \n", " cLT2FREQ | \n", " Unnamed: 4 | \n", " Unnamed: 5 | \n", " Unnamed: 6 | \n", " Unnamed: 7 | \n", " Unnamed: 8 | \n", " Unnamed: 9 | \n", " ... | \n", " Unnamed: 22 | \n", " Unnamed: 23 | \n", " Unnamed: 24 | \n", " Unnamed: 25 | \n", " Unnamed: 26 | \n", " Unnamed: 27 | \n", " Unnamed: 28 | \n", " Unnamed: 29 | \n", " Unnamed: 30 | \n", " Unnamed: 31 | \n", "
\n", " \n", " \n", " \n", " 0 | \n", " 0.889422 | \n", " 4766.865201 | \n", " 2 | \n", " 1.0 | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " ... | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", "
\n", " \n", " 1 | \n", " 2.310209 | \n", " 12381.589746 | \n", " 30 | \n", " 1.0 | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " ... | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", "
\n", " \n", " 2 | \n", " 2.740070 | \n", " 14685.431344 | \n", " 6 | \n", " 2.0 | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " ... | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", "
\n", " \n", " 3 | \n", " 1.775545 | \n", " 9516.049939 | \n", " 1 | \n", " 1.0 | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " ... | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", "
\n", " \n", " 4 | \n", " 0.732512 | \n", " 3925.907588 | \n", " 3 | \n", " 1.0 | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " ... | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", " NaN | \n", "
\n", " \n", "
\n", "
5 rows \u00d7 32 columns
\n", "
"], "text/plain": [" POIDLOG POIDSF cLT1FREQ cLT2FREQ Unnamed: 4 Unnamed: 5 \\\n", "0 0.889422 4766.865201 2 1.0 NaN NaN \n", "1 2.310209 12381.589746 30 1.0 NaN NaN \n", "2 2.740070 14685.431344 6 2.0 NaN NaN \n", "3 1.775545 9516.049939 1 1.0 NaN NaN \n", "4 0.732512 3925.907588 3 1.0 NaN NaN \n", "\n", " Unnamed: 6 Unnamed: 7 Unnamed: 8 Unnamed: 9 ... Unnamed: 22 \\\n", "0 NaN NaN NaN NaN ... NaN \n", "1 NaN NaN NaN NaN ... NaN \n", "2 NaN NaN NaN NaN ... NaN \n", "3 NaN NaN NaN NaN ... NaN \n", "4 NaN NaN NaN NaN ... NaN \n", "\n", " Unnamed: 23 Unnamed: 24 Unnamed: 25 Unnamed: 26 Unnamed: 27 \\\n", "0 NaN NaN NaN NaN NaN \n", "1 NaN NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN NaN \n", "\n", " Unnamed: 28 Unnamed: 29 Unnamed: 30 Unnamed: 31 \n", "0 NaN NaN NaN NaN \n", "1 NaN NaN NaN NaN \n", "2 NaN NaN NaN NaN \n", "3 NaN NaN NaN NaN \n", "4 NaN NaN NaN NaN \n", "\n", "[5 rows x 32 columns]"]}, "execution_count": 3, "metadata": {}, "output_type": "execute_result"}], "source": ["from pyquickhelper.loghelper import get_url_content\n", "import pandas, io\n", "from ensae_teaching_cs.data import donnees_enquete_2003_television\n", "text = donnees_enquete_2003_television()\n", "df = pandas.read_csv(text, sep=\"\\t\")\n", "df.head()"]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["{0.0, 1.0, 2.0, 3.0}\n"]}], "source": ["df = df [[\"POIDLOG\",\"POIDSF\",\"cLT1FREQ\",\"cLT2FREQ\"]] # question 1\n", "fill = df.copy()\n", "fill.cLT2FREQ.fillna(0, inplace=True)\n", "distinct = set(fill[\"cLT2FREQ\"]) # question 2\n", "print(distinct)"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["8403 7386\n"]}, {"data": {"text/html": ["\n", "
\n", " \n", " \n", " | \n", " POIDLOG | \n", " POIDSF | \n", " cLT1FREQ | \n", " cLT2FREQ | \n", "
\n", " \n", " \n", " \n", " 8397 | \n", " 0.502091 | \n", " 2690.961176 | \n", " 3 | \n", " 1 | \n", "
\n", " \n", " 8398 | \n", " 0.306852 | \n", " 1644.574141 | \n", " 6 | \n", " 1 | \n", "
\n", " \n", " 8399 | \n", " 2.501181 | \n", " 13405.104689 | \n", " 6 | \n", " 1 | \n", "
\n", " \n", " 8400 | \n", " 1.382758 | \n", " 7410.905653 | \n", " 1 | \n", " 1 | \n", "
\n", " \n", " 8401 | \n", " 0.343340 | \n", " 1840.132652 | \n", " 3 | \n", " 1 | \n", "
\n", " \n", "
\n", "
"], "text/plain": [" POIDLOG POIDSF cLT1FREQ cLT2FREQ\n", "8397 0.502091 2690.961176 3 1\n", "8398 0.306852 1644.574141 6 1\n", "8399 2.501181 13405.104689 6 1\n", "8400 1.382758 7410.905653 1 1\n", "8401 0.343340 1840.132652 3 1"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["notnull = df [ ~df.cLT2FREQ.isnull() ] # question 3\n", "print(len(df),len(notnull))\n", "notnull.tail()"]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": ["notnull.to_excel(\"data.xlsx\") # question 4"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Pour lancer Excel, vous pouvez juste \u00e9crire ceci :"]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"data": {"text/plain": ["0"]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}], "source": ["import os\n", "os.system(\"data.xlsx\") # pour lancer Excel"]}, {"cell_type": "markdown", "metadata": {}, "source": ["Et vous devriez voir ce qui suit :"]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"data": {"image/png": "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\n", "text/plain": [""]}, "execution_count": 8, "metadata": {}, "output_type": "execute_result"}], "source": ["from pyquickhelper.helpgen import NbImage\n", "NbImage(\"td10exc.png\")"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Exercice 2 : moyennes par groupes\n", " \n", "Toujours avec le m\u00eame jeu de donn\u00e9es ([marathon.txt](http://www.xavierdupre.fr/enseignement/complements/marathon.txt)), on veut ajouter une ligne \u00e0 la fin du tableau crois\u00e9 dynamique contenant la moyenne en secondes des temps des marathons pour chaque ville."]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [{"data": {"text/html": ["\n", "
\n", " \n", " \n", " | \n", " ville | \n", " annee | \n", " temps | \n", " secondes | \n", "
\n", " \n", " \n", " \n", " 0 | \n", " PARIS | \n", " 2011 | \n", " 02:06:29 | \n", " 7589 | \n", "
\n", " \n", " 1 | \n", " PARIS | \n", " 2010 | \n", " 02:06:41 | \n", " 7601 | \n", "
\n", " \n", " 2 | \n", " PARIS | \n", " 2009 | \n", " 02:05:47 | \n", " 7547 | \n", "
\n", " \n", " 3 | \n", " PARIS | \n", " 2008 | \n", " 02:06:40 | \n", " 7600 | \n", "
\n", " \n", " 4 | \n", " PARIS | \n", " 2007 | \n", " 02:07:17 | \n", " 7637 | \n", "
\n", " \n", "
\n", "
"], "text/plain": [" ville annee temps secondes\n", "0 PARIS 2011 02:06:29 7589\n", "1 PARIS 2010 02:06:41 7601\n", "2 PARIS 2009 02:05:47 7547\n", "3 PARIS 2008 02:06:40 7600\n", "4 PARIS 2007 02:07:17 7637"]}, "execution_count": 9, "metadata": {}, "output_type": "execute_result"}], "source": ["from ensae_teaching_cs.data import marathon\n", "import pandas\n", "df = pandas.read_csv(marathon(filename=True), \n", " sep=\"\\t\", names=[\"ville\", \"annee\", \"temps\",\"secondes\"])\n", "df.head()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["La solution requiert trois \u00e9tapes.\n", "\n", "1. Pour avoir la moyenne par villes, il faut grouper les lignes associ\u00e9es \u00e0 la m\u00eame villes.\n", "2. Ensuite, il faut introduire ces moyennes dans la table initiale : on fusionne.\n", "3. On effectue le m\u00eame pivot que dans l'\u00e9nonc\u00e9."]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"data": {"text/html": ["\n", "
\n", " \n", " \n", " | \n", " ville | \n", " secondes | \n", "
\n", " \n", " \n", " \n", " 0 | \n", " AMSTERDAM | \n", " 7883.371429 | \n", "
\n", " \n", " 1 | \n", " BERLIN | \n", " 7922.315789 | \n", "
\n", " \n", " 2 | \n", " BOSTON | \n", " 7891.061224 | \n", "
\n", " \n", " 3 | \n", " CHICAGO | \n", " 7815.909091 | \n", "
\n", " \n", " 4 | \n", " FUKUOKA | \n", " 8075.187500 | \n", "
\n", " \n", "
\n", "
"], "text/plain": [" ville secondes\n", "0 AMSTERDAM 7883.371429\n", "1 BERLIN 7922.315789\n", "2 BOSTON 7891.061224\n", "3 CHICAGO 7815.909091\n", "4 FUKUOKA 8075.187500"]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["# \u00e9tape 1\n", "# par d\u00e9faut, la m\u00e9thode groupby utilise la cl\u00e9 de group comme index\n", "# pour ne pas le faire, il faut pr\u00e9ciser as_index = False\n", "gr = df[[\"ville\",\"secondes\"]].groupby(\"ville\", as_index=False).mean()\n", "gr.head()"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"data": {"text/html": ["\n", "
\n", " \n", " \n", " | \n", " ville | \n", " annee | \n", " temps | \n", " secondes_x | \n", " secondes_y | \n", "
\n", " \n", " \n", " \n", " 0 | \n", " PARIS | \n", " 2011 | \n", " 02:06:29 | \n", " 7589 | \n", " 7937.028571 | \n", "
\n", " \n", " 1 | \n", " PARIS | \n", " 2010 | \n", " 02:06:41 | \n", " 7601 | \n", " 7937.028571 | \n", "
\n", " \n", " 2 | \n", " PARIS | \n", " 2009 | \n", " 02:05:47 | \n", " 7547 | \n", " 7937.028571 | \n", "
\n", " \n", " 3 | \n", " PARIS | \n", " 2008 | \n", " 02:06:40 | \n", " 7600 | \n", " 7937.028571 | \n", "
\n", " \n", " 4 | \n", " PARIS | \n", " 2007 | \n", " 02:07:17 | \n", " 7637 | \n", " 7937.028571 | \n", "
\n", " \n", "
\n", "
"], "text/plain": [" ville annee temps secondes_x secondes_y\n", "0 PARIS 2011 02:06:29 7589 7937.028571\n", "1 PARIS 2010 02:06:41 7601 7937.028571\n", "2 PARIS 2009 02:05:47 7547 7937.028571\n", "3 PARIS 2008 02:06:40 7600 7937.028571\n", "4 PARIS 2007 02:07:17 7637 7937.028571"]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["# \u00e9tape 2 - on ajoute une colonne\n", "tout = df.merge( gr, on=\"ville\")\n", "tout.head()"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"data": {"text/html": ["\n", "
\n", " \n", " \n", " ville | \n", " AMSTERDAM | \n", " BERLIN | \n", " BOSTON | \n", " CHICAGO | \n", " FUKUOKA | \n", " LONDON | \n", " NEW YORK | \n", " PARIS | \n", " STOCKOLM | \n", "
\n", " \n", " annee | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", "
\n", " \n", " \n", " \n", " 2007 | \n", " 7589 | \n", " 7466 | \n", " 8053 | \n", " 7871 | \n", " 7599 | \n", " 7661 | \n", " 7744 | \n", " 7637 | \n", " 8456 | \n", "
\n", " \n", " 2008 | \n", " 7672 | \n", " 7439 | \n", " 7665 | \n", " 7585 | \n", " 7570 | \n", " 7515 | \n", " 7723 | \n", " 7600 | \n", " 8163 | \n", "
\n", " \n", " 2009 | \n", " 7578 | \n", " 7568 | \n", " 7722 | \n", " 7541 | \n", " 7518 | \n", " 7510 | \n", " 7755 | \n", " 7547 | \n", " 8134 | \n", "
\n", " \n", " 2010 | \n", " 7544 | \n", " 7508 | \n", " 7552 | \n", " 7583 | \n", " 7704 | \n", " 7519 | \n", " 7694 | \n", " 7601 | \n", " 7968 | \n", "
\n", " \n", " 2011 | \n", " NaN | \n", " 7418 | \n", " 7382 | \n", " NaN | \n", " NaN | \n", " 7480 | \n", " NaN | \n", " 7589 | \n", " 8047 | \n", "
\n", " \n", "
\n", "
"], "text/plain": ["ville AMSTERDAM BERLIN BOSTON CHICAGO FUKUOKA LONDON NEW YORK PARIS \\\n", "annee \n", "2007 7589 7466 8053 7871 7599 7661 7744 7637 \n", "2008 7672 7439 7665 7585 7570 7515 7723 7600 \n", "2009 7578 7568 7722 7541 7518 7510 7755 7547 \n", "2010 7544 7508 7552 7583 7704 7519 7694 7601 \n", "2011 NaN 7418 7382 NaN NaN 7480 NaN 7589 \n", "\n", "ville STOCKOLM \n", "annee \n", "2007 8456 \n", "2008 8163 \n", "2009 8134 \n", "2010 7968 \n", "2011 8047 "]}, "execution_count": 12, "metadata": {}, "output_type": "execute_result"}], "source": ["# \u00e9tape 3\n", "piv = tout.pivot(\"annee\",\"ville\",\"secondes_x\")\n", "piv.tail()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["A partir de l\u00e0, on ne voit pas trop comment s'en sortir. Voici ce que je propose :\n", "\n", "1. On effectue un pivot sur la petite matrice des moyennes.\n", "2. On ajoute ce second pivot avec le premier (celui de l'\u00e9nonc\u00e9)."]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"data": {"text/html": ["\n", "
\n", " \n", " \n", " ville | \n", " AMSTERDAM | \n", " BERLIN | \n", " BOSTON | \n", " CHICAGO | \n", " FUKUOKA | \n", " LONDON | \n", " NEW YORK | \n", " PARIS | \n", " STOCKOLM | \n", "
\n", " \n", " annee | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", "
\n", " \n", " \n", " \n", " moyenne | \n", " 7883.371429 | \n", " 7922.315789 | \n", " 7891.061224 | \n", " 7815.909091 | \n", " 8075.1875 | \n", " 7695.16129 | \n", " 7928.560976 | \n", " 7937.028571 | \n", " 8133.393939 | \n", "
\n", " \n", "
\n", "
"], "text/plain": ["ville AMSTERDAM BERLIN BOSTON CHICAGO FUKUOKA \\\n", "annee \n", "moyenne 7883.371429 7922.315789 7891.061224 7815.909091 8075.1875 \n", "\n", "ville LONDON NEW YORK PARIS STOCKOLM \n", "annee \n", "moyenne 7695.16129 7928.560976 7937.028571 8133.393939 "]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["gr[\"annee\"] = \"moyenne\"\n", "pivmean = gr.pivot(\"annee\",\"ville\",\"secondes\")\n", "pivmean"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"data": {"text/html": ["\n", "
\n", " \n", " \n", " ville | \n", " AMSTERDAM | \n", " BERLIN | \n", " BOSTON | \n", " CHICAGO | \n", " FUKUOKA | \n", " LONDON | \n", " NEW YORK | \n", " PARIS | \n", " STOCKOLM | \n", "
\n", " \n", " annee | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", "
\n", " \n", " \n", " \n", " 2008 | \n", " 7672.000000 | \n", " 7439.000000 | \n", " 7665.000000 | \n", " 7585.000000 | \n", " 7570.0000 | \n", " 7515.00000 | \n", " 7723.000000 | \n", " 7600.000000 | \n", " 8163.000000 | \n", "
\n", " \n", " 2009 | \n", " 7578.000000 | \n", " 7568.000000 | \n", " 7722.000000 | \n", " 7541.000000 | \n", " 7518.0000 | \n", " 7510.00000 | \n", " 7755.000000 | \n", " 7547.000000 | \n", " 8134.000000 | \n", "
\n", " \n", " 2010 | \n", " 7544.000000 | \n", " 7508.000000 | \n", " 7552.000000 | \n", " 7583.000000 | \n", " 7704.0000 | \n", " 7519.00000 | \n", " 7694.000000 | \n", " 7601.000000 | \n", " 7968.000000 | \n", "
\n", " \n", " 2011 | \n", " NaN | \n", " 7418.000000 | \n", " 7382.000000 | \n", " NaN | \n", " NaN | \n", " 7480.00000 | \n", " NaN | \n", " 7589.000000 | \n", " 8047.000000 | \n", "
\n", " \n", " moyenne | \n", " 7883.371429 | \n", " 7922.315789 | \n", " 7891.061224 | \n", " 7815.909091 | \n", " 8075.1875 | \n", " 7695.16129 | \n", " 7928.560976 | \n", " 7937.028571 | \n", " 8133.393939 | \n", "
\n", " \n", "
\n", "
"], "text/plain": ["ville AMSTERDAM BERLIN BOSTON CHICAGO FUKUOKA \\\n", "annee \n", "2008 7672.000000 7439.000000 7665.000000 7585.000000 7570.0000 \n", "2009 7578.000000 7568.000000 7722.000000 7541.000000 7518.0000 \n", "2010 7544.000000 7508.000000 7552.000000 7583.000000 7704.0000 \n", "2011 NaN 7418.000000 7382.000000 NaN NaN \n", "moyenne 7883.371429 7922.315789 7891.061224 7815.909091 8075.1875 \n", "\n", "ville LONDON NEW YORK PARIS STOCKOLM \n", "annee \n", "2008 7515.00000 7723.000000 7600.000000 8163.000000 \n", "2009 7510.00000 7755.000000 7547.000000 8134.000000 \n", "2010 7519.00000 7694.000000 7601.000000 7968.000000 \n", "2011 7480.00000 NaN 7589.000000 8047.000000 \n", "moyenne 7695.16129 7928.560976 7937.028571 8133.393939 "]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["piv = df.pivot(\"annee\",\"ville\",\"secondes\")\n", "pandas.concat( [ piv, pivmean ]).tail()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["En r\u00e9sum\u00e9, cela donne (j'ajoute aussi le nombre de marathons courus) :"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"text/html": ["\n", "
\n", " \n", " \n", " ville | \n", " AMSTERDAM | \n", " BERLIN | \n", " BOSTON | \n", " CHICAGO | \n", " FUKUOKA | \n", " LONDON | \n", " NEW YORK | \n", " PARIS | \n", " STOCKOLM | \n", "
\n", " \n", " annee | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", "
\n", " \n", " \n", " \n", " 2009 | \n", " 7578.000000 | \n", " 7568.000000 | \n", " 7722.000000 | \n", " 7541.000000 | \n", " 7518.0000 | \n", " 7510.00000 | \n", " 7755.000000 | \n", " 7547.000000 | \n", " 8134.000000 | \n", "
\n", " \n", " 2010 | \n", " 7544.000000 | \n", " 7508.000000 | \n", " 7552.000000 | \n", " 7583.000000 | \n", " 7704.0000 | \n", " 7519.00000 | \n", " 7694.000000 | \n", " 7601.000000 | \n", " 7968.000000 | \n", "
\n", " \n", " 2011 | \n", " NaN | \n", " 7418.000000 | \n", " 7382.000000 | \n", " NaN | \n", " NaN | \n", " 7480.00000 | \n", " NaN | \n", " 7589.000000 | \n", " 8047.000000 | \n", "
\n", " \n", " moyenne | \n", " 7883.371429 | \n", " 7922.315789 | \n", " 7891.061224 | \n", " 7815.909091 | \n", " 8075.1875 | \n", " 7695.16129 | \n", " 7928.560976 | \n", " 7937.028571 | \n", " 8133.393939 | \n", "
\n", " \n", " nb | \n", " 35.000000 | \n", " 38.000000 | \n", " 49.000000 | \n", " 33.000000 | \n", " 64.0000 | \n", " 31.00000 | \n", " 41.000000 | \n", " 35.000000 | \n", " 33.000000 | \n", "
\n", " \n", "
\n", "
"], "text/plain": ["ville AMSTERDAM BERLIN BOSTON CHICAGO FUKUOKA \\\n", "annee \n", "2009 7578.000000 7568.000000 7722.000000 7541.000000 7518.0000 \n", "2010 7544.000000 7508.000000 7552.000000 7583.000000 7704.0000 \n", "2011 NaN 7418.000000 7382.000000 NaN NaN \n", "moyenne 7883.371429 7922.315789 7891.061224 7815.909091 8075.1875 \n", "nb 35.000000 38.000000 49.000000 33.000000 64.0000 \n", "\n", "ville LONDON NEW YORK PARIS STOCKOLM \n", "annee \n", "2009 7510.00000 7755.000000 7547.000000 8134.000000 \n", "2010 7519.00000 7694.000000 7601.000000 7968.000000 \n", "2011 7480.00000 NaN 7589.000000 8047.000000 \n", "moyenne 7695.16129 7928.560976 7937.028571 8133.393939 \n", "nb 31.00000 41.000000 35.000000 33.000000 "]}, "execution_count": 15, "metadata": {}, "output_type": "execute_result"}], "source": ["from ensae_teaching_cs.data import marathon\n", "import pandas\n", "df = pandas.read_csv(marathon(filename=True), \n", " sep=\"\\t\", names=[\"ville\", \"annee\", \"temps\",\"secondes\"])\n", "gr = df[[\"ville\",\"secondes\"]].groupby(\"ville\", as_index=False).mean()\n", "gr[\"annee\"] = \"moyenne\"\n", "pivmean = gr.pivot(\"annee\",\"ville\",\"secondes\")\n", "piv = df.pivot(\"annee\",\"ville\",\"secondes\")\n", "\n", "# bizarrement, la m\u00e9thode count r\u00e9introduit l'index que je pensais avoir supprim\u00e9 avec\n", "# as_index=False.\n", "# je le supprime de nouveau avec la m\u00e9thode reset_index.\n", "# la fonction count ne compte que les valeurs non manquantes.\n", "df2 = df.copy()\n", "df2[\"nb\"]=1\n", "grc = df2[[\"ville\",\"secondes\",\"nb\"]].groupby(\"ville\", as_index=False).sum()\n", "grc[\"annee\"] = \"nb\"\n", "pivc = grc.pivot(\"annee\",\"ville\",\"nb\")\n", "\n", "res = pandas.concat( [ piv, pivmean, pivc ])\n", "res.tail()"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Exercice 3 : r\u00e9gression lin\u00e9aire\n", "\n", "On reproduit le d\u00e9but du programme propos\u00e9 par l'\u00e9nonc\u00e9."]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"data": {"text/html": ["\n", "
\n", " \n", " \n", " | \n", " ville | \n", " annee | \n", " temps | \n", " secondes | \n", " estPARIS | \n", " estBERLIN | \n", "
\n", " \n", " \n", " \n", " 0 | \n", " PARIS | \n", " 2011 | \n", " 02:06:29 | \n", " 7589 | \n", " 1 | \n", " 0 | \n", "
\n", " \n", " 1 | \n", " PARIS | \n", " 2010 | \n", " 02:06:41 | \n", " 7601 | \n", " 1 | \n", " 0 | \n", "
\n", " \n", " 2 | \n", " PARIS | \n", " 2009 | \n", " 02:05:47 | \n", " 7547 | \n", " 1 | \n", " 0 | \n", "
\n", " \n", "
\n", "
"], "text/plain": [" ville annee temps secondes estPARIS estBERLIN\n", "0 PARIS 2011 02:06:29 7589 1 0\n", "1 PARIS 2010 02:06:41 7601 1 0\n", "2 PARIS 2009 02:05:47 7547 1 0"]}, "execution_count": 16, "metadata": {}, "output_type": "execute_result"}], "source": ["import pandas\n", "from datetime import datetime, time\n", "from ensae_teaching_cs.data import marathon\n", "df = pandas.read_csv(marathon(filename=True), \n", " sep=\"\\t\", names=[\"ville\", \"annee\", \"temps\",\"secondes\"])\n", "df = df [ (df[\"ville\"] == \"BERLIN\") | (df[\"ville\"] == \"PARIS\") ] \n", "for v in [\"PARIS\",\"BERLIN\"]:\n", " df[\"est\" + v] = df.apply( lambda r : 1 if r[\"ville\"] == v else 0, axis=1)\n", "df.head(n = 3)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["On va d'abord convertir la matrice en matrice ``numpy.matrix`` puis faire les calculs avec les notations matricielles :"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"data": {"text/plain": ["matrix([[ -3.39257988e+01],\n", " [ 7.55705317e+04],\n", " [ 7.55194699e+04]])"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["import numpy\n", "Y = numpy.matrix(df[[\"secondes\"]].values)\n", "X = numpy.matrix(df[[\"annee\",\"estPARIS\",\"estBERLIN\"]].values)\n", "A = (X.T * X).I * X.T * Y\n", "A"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"data": {"text/plain": ["matrix([[ 7.58900000e+03, 7.34575036e+03, 1.00000000e+00],\n", " [ 7.60100000e+03, 7.37967616e+03, 1.00000000e+00],\n", " [ 7.54700000e+03, 7.41360196e+03, 1.00000000e+00],\n", " [ 7.60000000e+03, 7.44752776e+03, 1.00000000e+00],\n", " [ 7.63700000e+03, 7.48145356e+03, 1.00000000e+00],\n", " [ 7.68300000e+03, 7.51537936e+03, 1.00000000e+00],\n", " [ 7.68200000e+03, 7.54930516e+03, 1.00000000e+00],\n", " [ 7.73600000e+03, 7.58323096e+03, 1.00000000e+00],\n", " [ 7.59300000e+03, 7.61715675e+03, 1.00000000e+00],\n", " [ 7.69800000e+03, 7.65108255e+03, 1.00000000e+00],\n", " [ 7.78000000e+03, 7.68500835e+03, 1.00000000e+00],\n", " [ 7.72900000e+03, 7.71893415e+03, 1.00000000e+00],\n", " [ 7.69000000e+03, 7.75285995e+03, 1.00000000e+00],\n", " [ 7.77700000e+03, 7.78678575e+03, 1.00000000e+00],\n", " [ 7.81400000e+03, 7.82071155e+03, 1.00000000e+00],\n", " [ 7.93800000e+03, 7.85463735e+03, 1.00000000e+00],\n", " [ 7.80600000e+03, 7.88856314e+03, 1.00000000e+00],\n", " [ 7.85600000e+03, 7.92248894e+03, 1.00000000e+00],\n", " [ 7.84600000e+03, 7.95641474e+03, 1.00000000e+00],\n", " [ 7.80300000e+03, 7.99034054e+03, 1.00000000e+00],\n", " [ 7.99000000e+03, 8.05819214e+03, 1.00000000e+00],\n", " [ 7.98300000e+03, 8.09211794e+03, 1.00000000e+00],\n", " [ 8.03300000e+03, 8.12604374e+03, 1.00000000e+00],\n", " [ 7.86900000e+03, 8.15996953e+03, 1.00000000e+00],\n", " [ 7.96400000e+03, 8.19389533e+03, 1.00000000e+00],\n", " [ 7.84900000e+03, 8.22782113e+03, 1.00000000e+00],\n", " [ 7.91800000e+03, 8.26174693e+03, 1.00000000e+00],\n", " [ 7.95800000e+03, 8.29567273e+03, 1.00000000e+00],\n", " [ 8.04700000e+03, 8.32959853e+03, 1.00000000e+00],\n", " [ 7.90400000e+03, 8.36352433e+03, 1.00000000e+00],\n", " [ 8.75000000e+03, 8.39745013e+03, 1.00000000e+00],\n", " [ 8.33300000e+03, 8.43137593e+03, 1.00000000e+00],\n", " [ 9.29500000e+03, 8.46530172e+03, 1.00000000e+00],\n", " [ 9.04100000e+03, 8.49922752e+03, 1.00000000e+00],\n", " [ 8.45700000e+03, 8.53315332e+03, 1.00000000e+00],\n", " [ 7.41800000e+03, 7.29468851e+03, 0.00000000e+00],\n", " [ 7.50800000e+03, 7.32861431e+03, 0.00000000e+00],\n", " [ 7.56800000e+03, 7.36254011e+03, 0.00000000e+00],\n", " [ 7.43900000e+03, 7.39646591e+03, 0.00000000e+00],\n", " [ 7.46600000e+03, 7.43039171e+03, 0.00000000e+00],\n", " [ 7.55600000e+03, 7.46431751e+03, 0.00000000e+00],\n", " [ 7.66100000e+03, 7.49824330e+03, 0.00000000e+00],\n", " [ 7.60400000e+03, 7.53216910e+03, 0.00000000e+00],\n", " [ 7.49500000e+03, 7.56609490e+03, 0.00000000e+00],\n", " [ 7.60700000e+03, 7.60002070e+03, 0.00000000e+00],\n", " [ 7.72700000e+03, 7.63394650e+03, 0.00000000e+00],\n", " [ 7.66200000e+03, 7.66787230e+03, 0.00000000e+00],\n", " [ 7.60400000e+03, 7.70179810e+03, 0.00000000e+00],\n", " [ 7.56500000e+03, 7.73572390e+03, 0.00000000e+00],\n", " [ 7.66100000e+03, 7.76964969e+03, 0.00000000e+00],\n", " [ 7.75500000e+03, 7.80357549e+03, 0.00000000e+00],\n", " [ 7.62200000e+03, 7.83750129e+03, 0.00000000e+00],\n", " [ 7.71100000e+03, 7.87142709e+03, 0.00000000e+00],\n", " [ 7.85700000e+03, 7.90535289e+03, 0.00000000e+00],\n", " [ 7.68700000e+03, 7.93927869e+03, 0.00000000e+00],\n", " [ 7.85700000e+03, 7.97320449e+03, 0.00000000e+00],\n", " [ 7.69600000e+03, 8.00713029e+03, 0.00000000e+00],\n", " [ 7.81100000e+03, 8.04105609e+03, 0.00000000e+00],\n", " [ 7.90500000e+03, 8.07498188e+03, 0.00000000e+00],\n", " [ 7.87100000e+03, 8.10890768e+03, 0.00000000e+00],\n", " [ 7.86300000e+03, 8.14283348e+03, 0.00000000e+00],\n", " [ 7.90300000e+03, 8.17675928e+03, 0.00000000e+00],\n", " [ 8.01500000e+03, 8.21068508e+03, 0.00000000e+00],\n", " [ 8.01700000e+03, 8.24461088e+03, 0.00000000e+00],\n", " [ 8.08700000e+03, 8.27853668e+03, 0.00000000e+00],\n", " [ 8.14200000e+03, 8.31246248e+03, 0.00000000e+00],\n", " [ 8.20800000e+03, 8.34638827e+03, 0.00000000e+00],\n", " [ 8.46900000e+03, 8.38031407e+03, 0.00000000e+00],\n", " [ 8.40300000e+03, 8.41423987e+03, 0.00000000e+00],\n", " [ 8.11900000e+03, 8.44816567e+03, 0.00000000e+00],\n", " [ 8.58800000e+03, 8.48209147e+03, 0.00000000e+00],\n", " [ 1.00280000e+04, 8.51601727e+03, 0.00000000e+00],\n", " [ 9.89300000e+03, 8.54994307e+03, 0.00000000e+00]])"]}, "execution_count": 18, "metadata": {}, "output_type": "execute_result"}], "source": ["numpy.column_stack([Y,X*A,X[:,1]])"]}, {"cell_type": "code", "execution_count": 18, "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.1"}}, "nbformat": 4, "nbformat_minor": 2}