Afficher la pageAnciennes révisionsLiens de retourAjouter au livre.Exporter en PDFHaut de page Cette page est en lecture seule. Vous pouvez afficher le texte source, mais ne pourrez pas le modifier. Contactez votre administrateur si vous pensez qu'il s'agit d'une erreur. ==== TP4 : analyse de données avec Pandas ==== **TBD** : Manu / Ronan * lecture / ecriture dans fichier plat et fichier csv * lecture sequentielle / flux de données * extraction / mise en forme / tableaux pandas **Installation et importation de modules** ==== Les notebooks Jupyter ==== Ce travail en autonomie sera réalisé à l'aide de "notebooks" fonctionnant sur l'interpréteur "jupyter". Les notebooks permettent d'écrire et d'exécuter des scripts python à l'aide d'un simple navigateur web. Les résultats d'exécution sont conservés et peuvent être retrouvés d'une session à l'autre. Ouvrez un terminal dans votre dossier de travail et tapez : jupyter-notebook Ceci ouvre un onglet de l'interpréteur jupyter dans votre navigateur. * Créez un notebook vierge via le menu ''new'' --> ''python 3'' * Ou bien cliquez sur le notebook sur lequel vous souhaitez travailler. {{http://researchcomputing.github.io/USGS_2014-07/Day03-Python/01_introduction.html|Introduction aux notebooks et à Python (en anglais)}} Pour utiliser un notebook, voir : <note tip> * {{http://nbviewer.jupyter.org/github/jupyter/notebook/blob/master/docs/source/examples/Notebook/What%20is%20the%20Jupyter%20Notebook.ipynb|1. What is the Jupyter notebook?}} * {{http://nbviewer.jupyter.org/github/jupyter/notebook/blob/master/docs/source/examples/Notebook/Notebook%20Basics.ipynb|2. Notebook basics}} * {{http://nbviewer.jupyter.org/github/jupyter/notebook/blob/master/docs/source/examples/Notebook/Running%20Code.ipynb|3. Running code}} * {{http://nbviewer.jupyter.org/github/jupyter/notebook/blob/master/docs/source/examples/Notebook/Working%20With%20Markdown%20Cells.ipynb|4. Working with Markdown cells}} ---- * {{https://www.youtube.com/embed/lmoNmY-cmSI|Une vidéo en anglais}} </note> ==== Numpy : vecteurs, matrices et algèbre linéaire en Python¶ ==== Le module 'numpy' permet des calculs numériques rapides en Python. Il fournit des vecteurs, matrices et les opérateurs matriciels sont rapides. Importez le module numpy. <code python> import numpy as np </code> * Numpy User Guide: {{http://docs.scipy.org/doc/numpy/user/index.html}} **Conseils importants :** * N'utilisez pas la classe ''matrix'' de numpy. Utilisez à la place des vecteurs à dimensions multiples. Cela fonctionne mieux. * Si vous travaillez avec des vecteurs, utilisez ''y=numpy.zeros(5)'' et pas ''y=numpy.zeros( (5, 1) )''. Avec la première manière vous pouvez écrire ''y[5]'' et pas avec la seconde. * L'indexation des vecteurs commence à 0. === Créer des ''arrays'' numpy¶ === Les vecteurs et les matrices peuvent être créés à partir de : * listes ou tuples * à l'aide de functions * en lisant des fichiers de données == Copie et "copie profonde" == Pour de bonnes performances, les affectations en Python ne copient pas les objets mais uniquement des références d'objets. Ainsi, quand des objets sont passés entre les fonctions, cela évite de surcharger la mémoire. Testez le code suivant: * une matrice 3x2 : <code python> A = np.array([[1, 2, 3], [4, 5, 6]]) print(A) </code> * Affecter A à B (Ceci ne crée pas une copie, mais une référence) <code python> B = A print(B) </code> * Si on mofifie B, qu'advient-il de A? <code python> B[1,1]=-5 print(A) print(B) </code> == Copier un array == Pour éviter ce comportement, afin d'obtenir un objet B indépendant de A, il est nécessaire d'utiliser la fonction ''copy'': <code python> C = np.copy(A) print(A) print(C) </code> <code python> C[-1,-1] = -10 print(A) print(C) </code> === Attributs des arrays === Les vecteurs et les matrices de numpy sont des objets disposant d'un certain nombre d'attributs et de méthodes attachés: * Les vecteurs et matrices ont une taille. Ceci est l'attribut ''shape'': <code python> A.shape </code> * Le nombre d'éléments est disponible à l'aide de l'attribut ''size'': <code python> A.size </code> * Le type de l'array peut être défini explicitement à l'aide de l'argument ''dtype'': <code python> A.dtype </code> Le type peut être défini lors de l'initialisation: <code python> Mc = np.array([[1, 2], [3, 4]], dtype=complex) print(Mc) </code> === Fonctions permettant de générer des vecteurs et des matrices === Pour éviter de définir manuellement des matrices de grande taille, de nombreuses fonctions numpy permettent de générer des arrays de différentes formes. Parmi les plus courantes: * ''arange'' (la valeur finale n'est pas contenue dans le vecteur): <code python> # create a range x = np.arange(0, 10, 2) # arguments: start, stop, step print(x) </code> <code python> x = np.arange(-1, 1.1, 0.1) print(x) </code> * ''linspace'': <code python> # avec linspace, le début ET la fin sont inclus print(np.linspace(0, 10, 25)) </code> * ''logspace'': <code python> print(np.logspace(0, 10, 10, base=np.e)) </code> * Données aléatoires: <code python> from numpy import random # uniform random numbers in [0,1] print(random.rand(5,5)) # standard normal distributed random numbers print(random.randn(5,5)) </code> * zeros et uns: <code python> print(np.zeros((3,3))) print(np.ones((3,3,3),dtype=int)*5) </code> === Manipuler les arrays === == Indexation == en Python, l'indexation commence à 0. <code python> # M is a matrix, or a 2 dimensional array, taking two indices print(A) print(A[1,1]) </code> * Si on omet un indice d'un array multidimensionnel, la ligne complète est retournée (ou, plus généralement, un array de dimension N-1): <code python> print(A[1]) </code> * La même chose est obtenue en utilisant '':'' à la place d'un indice: <code python> print(A[1,:]) # row 1 print(A[:,0]) # column 0 </code> * Grâce à l'indexation, de nouvelles valeurs peuvent être affectées aux éléments: <code python> A[0,0] = -1 print(A) </code> * Marche aussi pour les lignes et les colonnes: <code python> A[1,:] = 0 A[:,2] = -1 print(A) </code> === Algèbre linéaire === Les opérations doivent doivent prendre en argument des vecteurs ou des matrices pour bénéficier d'une vitesse optimale (fonctions compilées). * Opérations avec des scalaires: <code python> v1 = np.arange(0, 5) print(v1) print(v1 * 2) print(v1 + 2) </code> * Le comportement par défaut correspond à des opérations terme à terme: <code python> print(v1 * v1) </code> * Produit scalaire: <code python> print np.dot(v1, v1) </code> Pour aller plus loin : * Tutoriel inspiré de : {{http://researchcomputing.github.io/USGS_2014-07/Day03-Python/03b_numpy_tutorial.html}} * {{https://scipy.github.io/old-wiki/pages/Tentative_NumPy_Tutorial}} * {{https://github.com/jrjohansson/scientific-python-lectures}} <code> git clone https://github.com/jrjohansson/scientific-python-lectures/ </code> ==== Matplotlib ==== Matplotlib est une librairie de visualisation des données extrêmement flexible et paramétrable, proposant un grand nombre de modes de visualisation des données (trait, barres, barres d'erreur, histogrammes, images, etc). Pour importer cette librairie : <code python> import matplotlib.pyplot as plt </code> dans un notebook, on ajoutera la commande "magique": <code> %matplotlib inline </code> === Un affichage simple === <code python> import numpy as np from numpy import random data = random.rand(20) plt.plot(np.arange(20), data, 'bo-') plt.show() </code> === Autres exemples === * Fermer toutes les figures: <code python> plt.close('all') # ferme toutes les figures </code> * Affichage simple: <code python> # Common plot x=np.linspace(0,2*np.pi,100) y=x z=np.sin(x) plt.figure(1) # new figure plt.plot(x,y,'g') # set x=y to the buffer plt.plot(x,z,'rx-') # add z=sin(x) to the buffer plt.xlabel('Axe des X') plt.ylabel('Axe des Y') plt.title('Figure de test') plt.legend(('y=x','y=sin(x)'),'best') plt.show() # we print everything! </code> * Multiplot: <code python> plt.figure(2) sub1=plt.subplot(121) plt.plot(x,y,'r') sub1.set_title('Graphe1') sub2=plt.subplot(122) plt.plot(x,y*y,'g') sub2.set_title('Graphe2') plt.show() </code> * Affichage logarithmique : <code python> plt.figure(3) plt.semilogx(x,y) # X log scale plt.figure(4) plt.semilogy(x,y) # Y log scale plt.figure(5) plt.loglog(x,y) # X and Y log scale plt.show() </code> === Pour aller plus loin === De nombreux exemples de scripts d'affichages sont disponibles {{https://matplotlib.org/gallery.html||ici}}. Testez-en quelques-uns. ==== Pandas ==== L'utilisation de données structurées dans un programme Python nécessite de faire appel à des librairies spécialisées. Nous utiliserons ici la librairie ''pandas'' qui sert à la mise en forme et à l'analyse des données. <code python> import pandas </code> On considère une série d’enregistrements concernant des ventes réalisées par un exportateur de véhicules miniatures. Pour chaque vente, il entre dans son registre de nombreuses informations : * nom de la société cliente * nom et prénom du contact, adresse, téléphone * nombre d'unités vendues * prix de vente * etc... Ces informations sont stockées dans un fichier au format ‘csv’ (comma separated values) : ''{{https://forge.centrale-marseille.fr/attachments/download/143/ventes.csv|ventes.csv}}''. Téléchargez ce fichier. Dans un premier temps, regardez son contenu avec un editeur de texte (**''geany''**, **''gedit''** ou autre...). La première ligne contient les noms des attributs (''NUM_COMMANDE'', ''QUANTITE'',...). Les ligne suivantes contiennent les valeurs d’attributs correspondant à une vente donnée. en tout plus de 2000 ventes sont répertoriées dans ce fichier. Ouvrez-le maintenant à l’aide d’un tableur (par exemple **''localc''**). Les données sont maintenant “rangées” en lignes et colonnes pour faciliter la lecture. Créez un dossier ''data'' dans votre répertoire de travail (celui qui contient les notebooks) et déplacez le fichier ''ventes.csv'' dans le dossier ''data''. == Lecture des données == Les données sontau format ''csv'', on utilise: * ''pandas.read_csv''. Voir {{http://www.xavierdupre.fr/app/ensae_teaching_cs/helpsphinx/notebooks/td2a_cenonce_session_1.html#dataframe-pandas|dataframes pandas}}. Pandas permet également de lire les données au format ''xls'' et ''xlsx'' (Excel). * Pandas permet de manipuler des données de type ''DataFrame''. Si ''d'' est votre ''Dataframe'' et que vous avez besoin de passer au format ''array'' de ''numpy'' : ''m = d.as_matrix()'' <code python> with open('ventes.csv') as f: data = pandas.read_csv(f) print(data) </code> avec ''data'' une structure de données de type ''DataFrame'' Testez les commandes suivantes : <code python> print(len(data)) </code> <code python> print(data.columns) </code> Syntaxe de type dictionnaire : <code python> print(data["VILLE"]) </code> <code python> print(data[["VILLE", "PAYS"]]) </code> Autre syntaxe : <code python> print(data.VILLE) </code> <code python> print(data.VILLE.head(10)) </code> Çà marche aussi avec la syntaxe "dictionnaire": <code python> print(data["VILLE"].head(10)) </code> === Modifier les données === La colonne montant contient des données aberrantes. Modifions les : <code python> data.MONTANT = data.PRIX_UNITAIRE data.MONTANT *= data.QUANTITE print(data.MONTANT) </code> === Sélectionner les données === <code python> selection = data[data.MONTANT > 6000] print(selection[["MONTANT","DATE_COMMANDE","VILLE","PAYS","NOM_CONTACT","PRENOM_CONTACT"]]) </code> === Opérateurs d'agrégation == * usage : statistique sur les données * principe : * opérateur d’aggrégation : * tout type de données : comptage (attention aux doublons) <code python> print(data["VILLE"].count()) print(data["VILLE"].drop_duplicates().count()) </code> * données quantitatives (et non qualitatives) : somme, moyenne, ecart-type (count, sum, mean, std, min, max, …) <code python> print(data["MONTANT"].mean()) print(data["MONTANT"].std()) </code> === Affichage === <code python> data["MONTANT"].hist() plt.show() </code> === Calcul par classes === ici la date: <code python> grouped = data.groupby('DATE_COMMANDE') print(grouped["NUM_COMMANDE"].count()) </code> * groupage multiples : <code python> grouped_multiple = data.groupby(['PAYS', 'VILLE']) print(grouped["NUM_COMMANDE"].count()) </code> Pour aller plus loin : * {{http://www.xavierdupre.fr/app/ensae_teaching_cs/helpsphinx/notebooks/td2a_cenonce_session_1.html|Une introduction très détaillée aux DataFrames (en Français)}} * {{http://synesthesiam.com/posts/an-introduction-to-pandas.html#getting-data-out|Introduction to Pandas (en anglais)}} <note tip> ** A faire ** * Trouvez le nombre de ventes, le nombre de clients référencés (sans doublons), et le nombre de références produits (sans doublons). * Afficher le nombre de client et le chiffre d'affaires * par pays * par pays puis par état * par pays puis par état puis par ville * Donnez le nombre de ventes en fonction du mois pour l'année 2004 * Donnez le chiffre d’affaires par année et trimestre pour les ventes réalisées aux états unis * Quelle est la catégorie de véhicules la plus vendue? </note> === Tables Pivot === Agrégation des données selon différents attributs/dimensions exemple : on représente les ventes selon (1) la dimension géographique (pays, état) et (2) la dimension temporelle (les trimestres et mois de l'année) <code python> T = pandas.pivot_table(data, values = 'MONTANT', index = ['PAYS','VILLE'], columns = ['TRIMESTRE','MOIS'], aggfunc=np.sum) print(T) </code> <code python> T.plot(kind='bar', subplots = 'True') plt.show() </code> Evolution des ventes au cours de l'année pour la France seulement: <code python> selection = data[data.PAYS == "France"] T2 = pandas.pivot_table(selection, values = 'MONTANT', index = ['TRIMESTRE','MOIS'], columns = ['PAYS','VILLE'], aggfunc=np.sum) print(T2) T2.plot(kind='bar', subplots = 'True') plt.show() </code> <note tip> ** A faire ** * Donnez le nombre de ventes par catégorie pour chaque trimestre et mois de l’année. Choisissez le graphique le plus adapté pour représenter les données. * Donnez le montant moyen des ventes par pays et par ville, pour chaque catégorie de produits. Choisissez le graphique le plus adapté pour représenter les données. </note> Pour aller plus loin: * {{http://www.xavierdupre.fr/app/ensae_teaching_cs/helpsphinx/notebooks/td1a_cenonce_session_12.html#cartographie|Cartographier les données}} * {{http://geopandas.org/index.html|Géopandas}} === Exercice complet === **Télécharger un jeux de données** Télécharger l'archive {{ftp://ftp.nhtsa.dot.gov/GES/GES12/GES12_Flatfile.zip}} Déplacer et extraire le dossier. Nous nous intéresserons au fichier PERSONT.TXT Dans un terminal faire: ls head 'PATH_TO/GES12_Flatfile/PERSON.TXT' <code> input_file_path = os.path.join("PATH_TO", '/GES12_Flatfile/PERSON.TXT') df = pd.read_csv(input_file_path, delimiter='\t') print (df) </code> df est une structure panda <code> # Les types des colonnes d'un data frame sont inférés à partir des valeurs print(df.dtypes) </code> <code> # Vous pouvez connaitre les colonnes et les attributs d'un data frame avec TAB # en tapant df.<TAB> print(df.AGE) </code> **Visualiser les données** <code> #Premiers et derniers éléments print(df.head()) print(df.tail(2)) </code> <code> print(df[:2]) print(df.index) print(df.describe()) </code> <code> #transposition print(df.T) </code> <code> #Tri suivant un axe print(df.sort_index(axis=1, ascending=False)) </code> <code> # Le tableau numpy sous jacent au data frame print(df.values) print(df.values.shape) </code> **Selection** Accès aux lignes et colonnes par loc et iloc <code> print (df['AGE']) print (df.AGE) </code> <code> print(df.loc[:,['VEH_NO','PER_NO', 'PER_TYP']]) print(df.loc[3:5,['VEH_NO','PER_NO', 'PER_TYP']]) </code> <code> # Accès aux cases par l'index entier print(df.iloc[3]) print(df.iloc[3:5,0:2]) </code> <code> print(df[df.AGE > 80]) </code> **Entrer des valeurs** <code> df2 = df.copy() df2['PER_NO'] =1 print(df2) </code> <code> print (df2.shape) # Eliminer les lignes avec un champs quelconque indéfini df2 = df2.dropna(how='any') print (df2.shape) # Remplacer les valeurs manquantes par 5 print (df2.fillna(value=5)) </code> <code> print (pd.isnull(df2)) </code> **Calculs simples** <code> print (df.mean()) print( df.mean(1)) </code> **Histograms** <code> # Histogramme des types de dommages s = df.INJ_SEV.value_counts() print(s) </code> <code> s.hist() print (s.index, s.values) p = pd.Series(s.index, index=s.values) print (p) p.hist() plt.hist( s.values) plt.show() </code> **Merge jointure** <code> # Créer un fichier ou l'on dispose d'une ligne par passager, avec ses infos, et avec les infos associées à son conducteur # Par jointure sur nO vehicule et casenum des drivers = infos sur les conducteurs drivers = df[df.PER_TYP==1] # et des passagers passengers =df[df['PER_TYP']==2] passengers = passengers[['CASENUM' ,'VEH_NO', 'PER_NO','INJ_SEV']] new_data = pd.merge (drivers, passengers, on=['CASENUM','VEH_NO' ], how='inner',left_index=True,copy=False) print(new_data.head()) </code> <code> # L'opérateur sum ne s'applique qu'aux attributes de type nombre. # on peut grouper sur plusieurs attributs avec ['Atribut A', 'Attribut B'] print(df.groupby('AGE').sum()) </code> **Input/output** <code> df.to_csv('foo.csv') !ls pd.read_csv('foo.csv') </code> ==== Pour aller plus loin ==== Tutoriel : * {{http://researchcomputing.github.io/USGS_2014-07/Day03-Python/03_overview.html}} Données : * {{https://s3.amazonaws.com/research_computing_tutorials/hamlet.txt}} ==== Données supplémentaires ==== * {{https://s3.amazonaws.com/research_computing_tutorials/users.dat}} * {{https://s3.amazonaws.com/research_computing_tutorials/movies.dat}} * {{https://s3.amazonaws.com/research_computing_tutorials/ratings.dat}} * {{https://gist.githubusercontent.com/noamross/e5d3e859aa0c794be10b/raw/b999fb4425b54c63cab088c0ce2c0d6ce961a563/cars.csv}} tc_info/tpa3.txt Dernière modification : 2019/11/29 14:32de edauce