.. _td1acorrectionsession10rst: =========================================== 1A.data - DataFrame et Matrice (correction) =========================================== .. only:: html **Links:** :download:`notebook `, :downloadlink:`html `, :download:`python `, :downloadlink:`slides `, :githublink:`GitHub|_doc/notebooks/td1a_dfnp/td1a_correction_session_10.ipynb|*` Correction. .. code:: ipython3 from jyquickhelper import add_notebook_menu add_notebook_menu() .. contents:: :local: Exercice 1 : créer un fichier Excel ----------------------------------- On souhaite récupérer les données `donnees_enquete_2003_television.txt `__ (source : `INSEE `__). - ``POIDSLOG`` : Pondération individuelle relative - ``POIDSF`` : Variable de pondération individuelle - ``cLT1FREQ`` : Nombre d’heures en moyenne passées à regarder la télévision - ``cLT2FREQ`` : Unité de temps utilisée pour compter le nombre d’heures passées à regarder la télévision, cette unité est représentée par les quatre valeurs suivantes - 0 : non concerné - 1 : jour - 2 : semaine - 3 : mois Ensuite, on veut : 1. Supprimer les colonnes vides 2. Obtenir les valeurs distinctes pour la colonne ``cLT2FREQ`` 3. Modifier la matrice pour enlever les lignes pour lesquelles l’unité de temps (cLT2FREQ) n’est pas renseignée ou égale à zéro. 4. Sauver le résultat au format Excel. Vous aurez peut-être besoin des fonctions suivantes : - `numpy.isnan `__ - `DataFrame.apply `__ - `DataFrame.fillna `__ ou `DataFrame.isnull `__ - `DataFrame.copy `__ .. code:: ipython3 from pyquickhelper.loghelper import get_url_content import pandas, io from ensae_teaching_cs.data import donnees_enquete_2003_television text = donnees_enquete_2003_television() df = pandas.read_csv(text, sep="\t") df.head() .. raw:: html
POIDLOG POIDSF cLT1FREQ cLT2FREQ Unnamed: 4 Unnamed: 5 Unnamed: 6 Unnamed: 7 Unnamed: 8 Unnamed: 9 ... Unnamed: 22 Unnamed: 23 Unnamed: 24 Unnamed: 25 Unnamed: 26 Unnamed: 27 Unnamed: 28 Unnamed: 29 Unnamed: 30 Unnamed: 31
0 0.889422 4766.865201 2 1.0 NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 2.310209 12381.589746 30 1.0 NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 2.740070 14685.431344 6 2.0 NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 1.775545 9516.049939 1 1.0 NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 0.732512 3925.907588 3 1.0 NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

5 rows × 32 columns

.. code:: ipython3 df = df [["POIDLOG","POIDSF","cLT1FREQ","cLT2FREQ"]] # question 1 fill = df.copy() fill.cLT2FREQ.fillna(0, inplace=True) distinct = set(fill["cLT2FREQ"]) # question 2 print(distinct) .. parsed-literal:: {0.0, 1.0, 2.0, 3.0} .. code:: ipython3 notnull = df [ ~df.cLT2FREQ.isnull() ] # question 3 print(len(df),len(notnull)) notnull.tail() .. parsed-literal:: 8403 7386 .. raw:: html
POIDLOG POIDSF cLT1FREQ cLT2FREQ
8397 0.502091 2690.961176 3 1
8398 0.306852 1644.574141 6 1
8399 2.501181 13405.104689 6 1
8400 1.382758 7410.905653 1 1
8401 0.343340 1840.132652 3 1
.. code:: ipython3 notnull.to_excel("data.xlsx") # question 4 Pour lancer Excel, vous pouvez juste écrire ceci : .. code:: ipython3 import os os.system("data.xlsx") # pour lancer Excel .. parsed-literal:: 0 Et vous devriez voir ce qui suit : .. code:: ipython3 from pyquickhelper.helpgen import NbImage NbImage("td10exc.png") .. image:: td1a_correction_session_10_10_0.png Exercice 2 : moyennes par groupes --------------------------------- Toujours avec le même jeu de données (`marathon.txt `__), on veut ajouter une ligne à la fin du tableau croisé dynamique contenant la moyenne en secondes des temps des marathons pour chaque ville. .. code:: ipython3 from ensae_teaching_cs.data import marathon import pandas df = pandas.read_csv(marathon(filename=True), sep="\t", names=["ville", "annee", "temps","secondes"]) df.head() .. raw:: html
ville annee temps secondes
0 PARIS 2011 02:06:29 7589
1 PARIS 2010 02:06:41 7601
2 PARIS 2009 02:05:47 7547
3 PARIS 2008 02:06:40 7600
4 PARIS 2007 02:07:17 7637
La solution requiert trois étapes. 1. Pour avoir la moyenne par villes, il faut grouper les lignes associées à la même villes. 2. Ensuite, il faut introduire ces moyennes dans la table initiale : on fusionne. 3. On effectue le même pivot que dans l’énoncé. .. code:: ipython3 # étape 1 # par défaut, la méthode groupby utilise la clé de group comme index # pour ne pas le faire, il faut préciser as_index = False gr = df[["ville","secondes"]].groupby("ville", as_index=False).mean() gr.head() .. raw:: html
ville secondes
0 AMSTERDAM 7883.371429
1 BERLIN 7922.315789
2 BOSTON 7891.061224
3 CHICAGO 7815.909091
4 FUKUOKA 8075.187500
.. code:: ipython3 # étape 2 - on ajoute une colonne tout = df.merge( gr, on="ville") tout.head() .. raw:: html
ville annee temps secondes_x secondes_y
0 PARIS 2011 02:06:29 7589 7937.028571
1 PARIS 2010 02:06:41 7601 7937.028571
2 PARIS 2009 02:05:47 7547 7937.028571
3 PARIS 2008 02:06:40 7600 7937.028571
4 PARIS 2007 02:07:17 7637 7937.028571
.. code:: ipython3 # étape 3 piv = tout.pivot("annee","ville","secondes_x") piv.tail() .. raw:: html
ville AMSTERDAM BERLIN BOSTON CHICAGO FUKUOKA LONDON NEW YORK PARIS STOCKOLM
annee
2007 7589 7466 8053 7871 7599 7661 7744 7637 8456
2008 7672 7439 7665 7585 7570 7515 7723 7600 8163
2009 7578 7568 7722 7541 7518 7510 7755 7547 8134
2010 7544 7508 7552 7583 7704 7519 7694 7601 7968
2011 NaN 7418 7382 NaN NaN 7480 NaN 7589 8047
A partir de là, on ne voit pas trop comment s’en sortir. Voici ce que je propose : 1. On effectue un pivot sur la petite matrice des moyennes. 2. On ajoute ce second pivot avec le premier (celui de l’énoncé). .. code:: ipython3 gr["annee"] = "moyenne" pivmean = gr.pivot("annee","ville","secondes") pivmean .. raw:: html
ville AMSTERDAM BERLIN BOSTON CHICAGO FUKUOKA LONDON NEW YORK PARIS STOCKOLM
annee
moyenne 7883.371429 7922.315789 7891.061224 7815.909091 8075.1875 7695.16129 7928.560976 7937.028571 8133.393939
.. code:: ipython3 piv = df.pivot("annee","ville","secondes") pandas.concat( [ piv, pivmean ]).tail() .. raw:: html
ville AMSTERDAM BERLIN BOSTON CHICAGO FUKUOKA LONDON NEW YORK PARIS STOCKOLM
annee
2008 7672.000000 7439.000000 7665.000000 7585.000000 7570.0000 7515.00000 7723.000000 7600.000000 8163.000000
2009 7578.000000 7568.000000 7722.000000 7541.000000 7518.0000 7510.00000 7755.000000 7547.000000 8134.000000
2010 7544.000000 7508.000000 7552.000000 7583.000000 7704.0000 7519.00000 7694.000000 7601.000000 7968.000000
2011 NaN 7418.000000 7382.000000 NaN NaN 7480.00000 NaN 7589.000000 8047.000000
moyenne 7883.371429 7922.315789 7891.061224 7815.909091 8075.1875 7695.16129 7928.560976 7937.028571 8133.393939
En résumé, cela donne (j’ajoute aussi le nombre de marathons courus) : .. code:: ipython3 from ensae_teaching_cs.data import marathon import pandas df = pandas.read_csv(marathon(filename=True), sep="\t", names=["ville", "annee", "temps","secondes"]) gr = df[["ville","secondes"]].groupby("ville", as_index=False).mean() gr["annee"] = "moyenne" pivmean = gr.pivot("annee","ville","secondes") piv = df.pivot("annee","ville","secondes") # bizarrement, la méthode count réintroduit l'index que je pensais avoir supprimé avec # as_index=False. # je le supprime de nouveau avec la méthode reset_index. # la fonction count ne compte que les valeurs non manquantes. df2 = df.copy() df2["nb"]=1 grc = df2[["ville","secondes","nb"]].groupby("ville", as_index=False).sum() grc["annee"] = "nb" pivc = grc.pivot("annee","ville","nb") res = pandas.concat( [ piv, pivmean, pivc ]) res.tail() .. raw:: html
ville AMSTERDAM BERLIN BOSTON CHICAGO FUKUOKA LONDON NEW YORK PARIS STOCKOLM
annee
2009 7578.000000 7568.000000 7722.000000 7541.000000 7518.0000 7510.00000 7755.000000 7547.000000 8134.000000
2010 7544.000000 7508.000000 7552.000000 7583.000000 7704.0000 7519.00000 7694.000000 7601.000000 7968.000000
2011 NaN 7418.000000 7382.000000 NaN NaN 7480.00000 NaN 7589.000000 8047.000000
moyenne 7883.371429 7922.315789 7891.061224 7815.909091 8075.1875 7695.16129 7928.560976 7937.028571 8133.393939
nb 35.000000 38.000000 49.000000 33.000000 64.0000 31.00000 41.000000 35.000000 33.000000
Exercice 3 : régression linéaire -------------------------------- On reproduit le début du programme proposé par l’énoncé. .. code:: ipython3 import pandas from datetime import datetime, time from ensae_teaching_cs.data import marathon df = pandas.read_csv(marathon(filename=True), sep="\t", names=["ville", "annee", "temps","secondes"]) df = df [ (df["ville"] == "BERLIN") | (df["ville"] == "PARIS") ] for v in ["PARIS","BERLIN"]: df["est" + v] = df.apply( lambda r : 1 if r["ville"] == v else 0, axis=1) df.head(n = 3) .. raw:: html
ville annee temps secondes estPARIS estBERLIN
0 PARIS 2011 02:06:29 7589 1 0
1 PARIS 2010 02:06:41 7601 1 0
2 PARIS 2009 02:05:47 7547 1 0
On va d’abord convertir la matrice en matrice ``numpy.matrix`` puis faire les calculs avec les notations matricielles : .. code:: ipython3 import numpy Y = numpy.matrix(df[["secondes"]].values) X = numpy.matrix(df[["annee","estPARIS","estBERLIN"]].values) A = (X.T * X).I * X.T * Y A .. parsed-literal:: matrix([[ -3.39257988e+01], [ 7.55705317e+04], [ 7.55194699e+04]]) .. code:: ipython3 numpy.column_stack([Y,X*A,X[:,1]]) .. parsed-literal:: matrix([[ 7.58900000e+03, 7.34575036e+03, 1.00000000e+00], [ 7.60100000e+03, 7.37967616e+03, 1.00000000e+00], [ 7.54700000e+03, 7.41360196e+03, 1.00000000e+00], [ 7.60000000e+03, 7.44752776e+03, 1.00000000e+00], [ 7.63700000e+03, 7.48145356e+03, 1.00000000e+00], [ 7.68300000e+03, 7.51537936e+03, 1.00000000e+00], [ 7.68200000e+03, 7.54930516e+03, 1.00000000e+00], [ 7.73600000e+03, 7.58323096e+03, 1.00000000e+00], [ 7.59300000e+03, 7.61715675e+03, 1.00000000e+00], [ 7.69800000e+03, 7.65108255e+03, 1.00000000e+00], [ 7.78000000e+03, 7.68500835e+03, 1.00000000e+00], [ 7.72900000e+03, 7.71893415e+03, 1.00000000e+00], [ 7.69000000e+03, 7.75285995e+03, 1.00000000e+00], [ 7.77700000e+03, 7.78678575e+03, 1.00000000e+00], [ 7.81400000e+03, 7.82071155e+03, 1.00000000e+00], [ 7.93800000e+03, 7.85463735e+03, 1.00000000e+00], [ 7.80600000e+03, 7.88856314e+03, 1.00000000e+00], [ 7.85600000e+03, 7.92248894e+03, 1.00000000e+00], [ 7.84600000e+03, 7.95641474e+03, 1.00000000e+00], [ 7.80300000e+03, 7.99034054e+03, 1.00000000e+00], [ 7.99000000e+03, 8.05819214e+03, 1.00000000e+00], [ 7.98300000e+03, 8.09211794e+03, 1.00000000e+00], [ 8.03300000e+03, 8.12604374e+03, 1.00000000e+00], [ 7.86900000e+03, 8.15996953e+03, 1.00000000e+00], [ 7.96400000e+03, 8.19389533e+03, 1.00000000e+00], [ 7.84900000e+03, 8.22782113e+03, 1.00000000e+00], [ 7.91800000e+03, 8.26174693e+03, 1.00000000e+00], [ 7.95800000e+03, 8.29567273e+03, 1.00000000e+00], [ 8.04700000e+03, 8.32959853e+03, 1.00000000e+00], [ 7.90400000e+03, 8.36352433e+03, 1.00000000e+00], [ 8.75000000e+03, 8.39745013e+03, 1.00000000e+00], [ 8.33300000e+03, 8.43137593e+03, 1.00000000e+00], [ 9.29500000e+03, 8.46530172e+03, 1.00000000e+00], [ 9.04100000e+03, 8.49922752e+03, 1.00000000e+00], [ 8.45700000e+03, 8.53315332e+03, 1.00000000e+00], [ 7.41800000e+03, 7.29468851e+03, 0.00000000e+00], [ 7.50800000e+03, 7.32861431e+03, 0.00000000e+00], [ 7.56800000e+03, 7.36254011e+03, 0.00000000e+00], [ 7.43900000e+03, 7.39646591e+03, 0.00000000e+00], [ 7.46600000e+03, 7.43039171e+03, 0.00000000e+00], [ 7.55600000e+03, 7.46431751e+03, 0.00000000e+00], [ 7.66100000e+03, 7.49824330e+03, 0.00000000e+00], [ 7.60400000e+03, 7.53216910e+03, 0.00000000e+00], [ 7.49500000e+03, 7.56609490e+03, 0.00000000e+00], [ 7.60700000e+03, 7.60002070e+03, 0.00000000e+00], [ 7.72700000e+03, 7.63394650e+03, 0.00000000e+00], [ 7.66200000e+03, 7.66787230e+03, 0.00000000e+00], [ 7.60400000e+03, 7.70179810e+03, 0.00000000e+00], [ 7.56500000e+03, 7.73572390e+03, 0.00000000e+00], [ 7.66100000e+03, 7.76964969e+03, 0.00000000e+00], [ 7.75500000e+03, 7.80357549e+03, 0.00000000e+00], [ 7.62200000e+03, 7.83750129e+03, 0.00000000e+00], [ 7.71100000e+03, 7.87142709e+03, 0.00000000e+00], [ 7.85700000e+03, 7.90535289e+03, 0.00000000e+00], [ 7.68700000e+03, 7.93927869e+03, 0.00000000e+00], [ 7.85700000e+03, 7.97320449e+03, 0.00000000e+00], [ 7.69600000e+03, 8.00713029e+03, 0.00000000e+00], [ 7.81100000e+03, 8.04105609e+03, 0.00000000e+00], [ 7.90500000e+03, 8.07498188e+03, 0.00000000e+00], [ 7.87100000e+03, 8.10890768e+03, 0.00000000e+00], [ 7.86300000e+03, 8.14283348e+03, 0.00000000e+00], [ 7.90300000e+03, 8.17675928e+03, 0.00000000e+00], [ 8.01500000e+03, 8.21068508e+03, 0.00000000e+00], [ 8.01700000e+03, 8.24461088e+03, 0.00000000e+00], [ 8.08700000e+03, 8.27853668e+03, 0.00000000e+00], [ 8.14200000e+03, 8.31246248e+03, 0.00000000e+00], [ 8.20800000e+03, 8.34638827e+03, 0.00000000e+00], [ 8.46900000e+03, 8.38031407e+03, 0.00000000e+00], [ 8.40300000e+03, 8.41423987e+03, 0.00000000e+00], [ 8.11900000e+03, 8.44816567e+03, 0.00000000e+00], [ 8.58800000e+03, 8.48209147e+03, 0.00000000e+00], [ 1.00280000e+04, 8.51601727e+03, 0.00000000e+00], [ 9.89300000e+03, 8.54994307e+03, 0.00000000e+00]])