Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
tc_info:tpa3 [2019/01/15 12:52] – créée edauce | tc_info:tpa3 [2019/11/29 14:32] (Version actuelle) – edauce | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
+ | ==== 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 " | ||
+ | permettent d' | ||
+ | Les résultats d' | ||
+ | |||
+ | Ouvrez un terminal dans votre dossier de travail et tapez : | ||
+ | jupyter-notebook | ||
+ | Ceci ouvre un onglet de l' | ||
+ | * Créez un notebook vierge via le menu '' | ||
+ | * Ou bien cliquez sur le notebook sur lequel vous souhaitez travailler. | ||
+ | |||
+ | {{http:// | ||
+ | |||
+ | Pour utiliser un notebook, voir : | ||
+ | <note tip> | ||
+ | * {{http:// | ||
+ | * {{http:// | ||
+ | * {{http:// | ||
+ | * {{http:// | ||
+ | |||
+ | ---- | ||
+ | * {{https:// | ||
+ | </ | ||
+ | ==== Numpy : vecteurs, matrices et algèbre linéaire en Python¶ ==== | ||
+ | |||
+ | Le module ' | ||
+ | |||
+ | <code python> | ||
+ | import numpy as np | ||
+ | </ | ||
+ | |||
+ | * Numpy User Guide: {{http:// | ||
+ | |||
+ | **Conseils importants :** | ||
+ | * N' | ||
+ | * Si vous travaillez avec des vecteurs, utilisez '' | ||
+ | * L' | ||
+ | |||
+ | === Créer des '' | ||
+ | |||
+ | 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, | ||
+ | |||
+ | Testez le code suivant: | ||
+ | * une matrice 3x2 : | ||
+ | <code python> | ||
+ | A = np.array([[1, | ||
+ | print(A) | ||
+ | </ | ||
+ | * Affecter A à B (Ceci ne crée pas une copie, mais une référence) | ||
+ | <code python> | ||
+ | B = A | ||
+ | print(B) | ||
+ | </ | ||
+ | * Si on mofifie B, qu' | ||
+ | <code python> | ||
+ | B[1,1]=-5 | ||
+ | print(A) | ||
+ | print(B) | ||
+ | </ | ||
+ | |||
+ | == Copier un array == | ||
+ | Pour éviter ce comportement, | ||
+ | <code python> | ||
+ | C = np.copy(A) | ||
+ | print(A) | ||
+ | print(C) | ||
+ | </ | ||
+ | |||
+ | <code python> | ||
+ | C[-1,-1] = -10 | ||
+ | print(A) | ||
+ | print(C) | ||
+ | </ | ||
+ | |||
+ | === Attributs des arrays === | ||
+ | Les vecteurs et les matrices de numpy sont des objets disposant d'un certain nombre d' | ||
+ | * Les vecteurs et matrices ont une taille. Ceci est l' | ||
+ | <code python> | ||
+ | A.shape | ||
+ | </ | ||
+ | * Le nombre d' | ||
+ | <code python> | ||
+ | A.size | ||
+ | </ | ||
+ | * Le type de l' | ||
+ | <code python> | ||
+ | A.dtype | ||
+ | </ | ||
+ | Le type peut être défini lors de l' | ||
+ | <code python> | ||
+ | Mc = np.array([[1, | ||
+ | print(Mc) | ||
+ | </ | ||
+ | |||
+ | === 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: | ||
+ | |||
+ | * '' | ||
+ | <code python> | ||
+ | # create a range | ||
+ | x = np.arange(0, | ||
+ | print(x) | ||
+ | </ | ||
+ | <code python> | ||
+ | x = np.arange(-1, | ||
+ | print(x) | ||
+ | </ | ||
+ | * '' | ||
+ | <code python> | ||
+ | # avec linspace, le début ET la fin sont inclus | ||
+ | print(np.linspace(0, | ||
+ | </ | ||
+ | * '' | ||
+ | <code python> | ||
+ | print(np.logspace(0, | ||
+ | </ | ||
+ | * Données aléatoires: | ||
+ | <code python> | ||
+ | from numpy import random | ||
+ | # uniform random numbers in [0,1] | ||
+ | print(random.rand(5, | ||
+ | # standard normal distributed random numbers | ||
+ | print(random.randn(5, | ||
+ | </ | ||
+ | * zeros et uns: | ||
+ | <code python> | ||
+ | print(np.zeros((3, | ||
+ | print(np.ones((3, | ||
+ | </ | ||
+ | |||
+ | === Manipuler les arrays === | ||
+ | |||
+ | == Indexation == | ||
+ | en Python, l' | ||
+ | <code python> | ||
+ | # M is a matrix, or a 2 dimensional array, taking two indices | ||
+ | print(A) | ||
+ | print(A[1, | ||
+ | </ | ||
+ | * Si on omet un indice d'un array multidimensionnel, | ||
+ | <code python> | ||
+ | print(A[1]) | ||
+ | </ | ||
+ | * La même chose est obtenue en utilisant '':'' | ||
+ | <code python> | ||
+ | print(A[1,: | ||
+ | print(A[:, | ||
+ | </ | ||
+ | * Grâce à l' | ||
+ | <code python> | ||
+ | A[0,0] = -1 | ||
+ | print(A) | ||
+ | </ | ||
+ | * Marche aussi pour les lignes et les colonnes: | ||
+ | <code python> | ||
+ | A[1,:] = 0 | ||
+ | A[:,2] = -1 | ||
+ | print(A) | ||
+ | </ | ||
+ | |||
+ | === 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, | ||
+ | print(v1) | ||
+ | print(v1 * 2) | ||
+ | print(v1 + 2) | ||
+ | </ | ||
+ | * Le comportement par défaut correspond à des opérations terme à terme: | ||
+ | <code python> | ||
+ | print(v1 * v1) | ||
+ | </ | ||
+ | * Produit scalaire: | ||
+ | <code python> | ||
+ | print np.dot(v1, v1) | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | Pour aller plus loin : | ||
+ | * Tutoriel inspiré de : {{http:// | ||
+ | * {{https:// | ||
+ | * {{https:// | ||
+ | < | ||
+ | git clone https:// | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ==== Matplotlib ==== | ||
+ | |||
+ | Matplotlib est une librairie de visualisation des données extrêmement flexible et paramétrable, | ||
+ | |||
+ | |||
+ | |||
+ | Pour importer cette librairie : | ||
+ | <code python> | ||
+ | import matplotlib.pyplot as plt | ||
+ | </ | ||
+ | |||
+ | dans un notebook, on ajoutera la commande " | ||
+ | < | ||
+ | %matplotlib inline | ||
+ | </ | ||
+ | |||
+ | === Un affichage simple === | ||
+ | <code python> | ||
+ | import numpy as np | ||
+ | from numpy import random | ||
+ | |||
+ | data = random.rand(20) | ||
+ | plt.plot(np.arange(20), | ||
+ | plt.show() | ||
+ | </ | ||
+ | |||
+ | === Autres exemples === | ||
+ | |||
+ | * Fermer toutes les figures: | ||
+ | <code python> | ||
+ | plt.close(' | ||
+ | </ | ||
+ | * Affichage simple: | ||
+ | <code python> | ||
+ | # Common plot | ||
+ | x=np.linspace(0, | ||
+ | y=x | ||
+ | z=np.sin(x) | ||
+ | |||
+ | plt.figure(1) # new figure | ||
+ | plt.plot(x, | ||
+ | plt.plot(x, | ||
+ | plt.xlabel(' | ||
+ | plt.ylabel(' | ||
+ | plt.title(' | ||
+ | plt.legend((' | ||
+ | plt.show() # we print everything! | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | * Multiplot: | ||
+ | <code python> | ||
+ | plt.figure(2) | ||
+ | sub1=plt.subplot(121) | ||
+ | plt.plot(x, | ||
+ | sub1.set_title(' | ||
+ | sub2=plt.subplot(122) | ||
+ | plt.plot(x, | ||
+ | sub2.set_title(' | ||
+ | |||
+ | plt.show() | ||
+ | </ | ||
+ | |||
+ | * Affichage logarithmique : | ||
+ | <code python> | ||
+ | plt.figure(3) | ||
+ | plt.semilogx(x, | ||
+ | plt.figure(4) | ||
+ | plt.semilogy(x, | ||
+ | plt.figure(5) | ||
+ | plt.loglog(x, | ||
+ | |||
+ | plt.show() | ||
+ | </ | ||
+ | |||
+ | === Pour aller plus loin === | ||
+ | De nombreux exemples de scripts d' | ||
+ | |||
+ | ==== Pandas ==== | ||
+ | |||
+ | L' | ||
+ | <code python> | ||
+ | import pandas | ||
+ | </ | ||
+ | |||
+ | |||
+ | 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' | ||
+ | * prix de vente | ||
+ | * etc... | ||
+ | Ces informations sont stockées dans un fichier au format ‘csv’ (comma separated values) : '' | ||
+ | Téléchargez ce fichier. | ||
+ | |||
+ | Dans un premier temps, regardez son contenu avec un editeur de texte (**'' | ||
+ | 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 **'' | ||
+ | Les données sont maintenant “rangées” en lignes et colonnes pour faciliter la lecture. | ||
+ | |||
+ | Créez un dossier '' | ||
+ | |||
+ | == Lecture des données == | ||
+ | |||
+ | Les données sontau format '' | ||
+ | * '' | ||
+ | * Pandas permet de manipuler des données de type '' | ||
+ | |||
+ | |||
+ | <code python> | ||
+ | with open(' | ||
+ | data = pandas.read_csv(f) | ||
+ | print(data) | ||
+ | </ | ||
+ | avec '' | ||
+ | |||
+ | Testez les commandes suivantes : | ||
+ | <code python> | ||
+ | print(len(data)) | ||
+ | </ | ||
+ | <code python> | ||
+ | print(data.columns) | ||
+ | </ | ||
+ | Syntaxe de type dictionnaire : | ||
+ | <code python> | ||
+ | print(data[" | ||
+ | </ | ||
+ | <code python> | ||
+ | print(data[[" | ||
+ | </ | ||
+ | Autre syntaxe : | ||
+ | <code python> | ||
+ | print(data.VILLE) | ||
+ | </ | ||
+ | <code python> | ||
+ | print(data.VILLE.head(10)) | ||
+ | </ | ||
+ | Çà marche aussi avec la syntaxe " | ||
+ | <code python> | ||
+ | print(data[" | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | === 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) | ||
+ | </ | ||
+ | |||
+ | === Sélectionner les données === | ||
+ | <code python> | ||
+ | selection = data[data.MONTANT > 6000] | ||
+ | print(selection[[" | ||
+ | </ | ||
+ | |||
+ | === Opérateurs d' | ||
+ | |||
+ | * 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[" | ||
+ | print(data[" | ||
+ | </ | ||
+ | * données quantitatives (et non qualitatives) : somme, moyenne, ecart-type (count, sum, mean, std, min, max, …) | ||
+ | <code python> | ||
+ | print(data[" | ||
+ | print(data[" | ||
+ | </ | ||
+ | |||
+ | |||
+ | === Affichage === | ||
+ | <code python> | ||
+ | data[" | ||
+ | plt.show() | ||
+ | </ | ||
+ | |||
+ | === Calcul par classes | ||
+ | ici la date: | ||
+ | <code python> | ||
+ | grouped = data.groupby(' | ||
+ | print(grouped[" | ||
+ | </ | ||
+ | * groupage multiples : | ||
+ | <code python> | ||
+ | grouped_multiple = data.groupby([' | ||
+ | print(grouped[" | ||
+ | </ | ||
+ | |||
+ | Pour aller plus loin : | ||
+ | * {{http:// | ||
+ | * {{http:// | ||
+ | |||
+ | <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' | ||
+ | * 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' | ||
+ | * 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? | ||
+ | </ | ||
+ | === Tables Pivot === | ||
+ | |||
+ | Agrégation des données selon différents attributs/ | ||
+ | |||
+ | 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' | ||
+ | |||
+ | <code python> | ||
+ | T = pandas.pivot_table(data, | ||
+ | print(T) | ||
+ | </ | ||
+ | |||
+ | <code python> | ||
+ | T.plot(kind=' | ||
+ | plt.show() | ||
+ | </ | ||
+ | |||
+ | Evolution des ventes au cours de l' | ||
+ | <code python> | ||
+ | selection = data[data.PAYS == " | ||
+ | T2 = pandas.pivot_table(selection, | ||
+ | print(T2) | ||
+ | |||
+ | T2.plot(kind=' | ||
+ | plt.show() | ||
+ | </ | ||
+ | <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. | ||
+ | </ | ||
+ | |||
+ | Pour aller plus loin: | ||
+ | * {{http:// | ||
+ | * {{http:// | ||
+ | |||
+ | === Exercice complet === | ||
+ | |||
+ | **Télécharger un jeux de données** | ||
+ | Télécharger l' | ||
+ | Déplacer et extraire le dossier. | ||
+ | Nous nous intéresserons au fichier PERSONT.TXT | ||
+ | |||
+ | Dans un terminal faire: | ||
+ | |||
+ | ls | ||
+ | |||
+ | head ' | ||
+ | |||
+ | |||
+ | < | ||
+ | input_file_path = os.path.join(" | ||
+ | |||
+ | df = pd.read_csv(input_file_path, | ||
+ | print (df) | ||
+ | </ | ||
+ | |||
+ | df est une structure panda | ||
+ | |||
+ | < | ||
+ | # Les types des colonnes d'un data frame sont inférés à partir des valeurs | ||
+ | print(df.dtypes) | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | # Vous pouvez connaitre les colonnes et les attributs d'un data frame avec TAB | ||
+ | # en tapant df.< | ||
+ | print(df.AGE) | ||
+ | </ | ||
+ | |||
+ | **Visualiser les données** | ||
+ | |||
+ | < | ||
+ | #Premiers et derniers éléments | ||
+ | print(df.head()) | ||
+ | |||
+ | print(df.tail(2)) | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | print(df[: | ||
+ | print(df.index) | ||
+ | print(df.describe()) | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | # | ||
+ | print(df.T) | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | #Tri suivant un axe | ||
+ | print(df.sort_index(axis=1, | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | # Le tableau numpy sous jacent au data frame | ||
+ | print(df.values) | ||
+ | print(df.values.shape) | ||
+ | </ | ||
+ | |||
+ | **Selection** | ||
+ | Accès aux lignes et colonnes par loc et iloc | ||
+ | |||
+ | < | ||
+ | print (df[' | ||
+ | |||
+ | print (df.AGE) | ||
+ | </ | ||
+ | |||
+ | |||
+ | < | ||
+ | print(df.loc[:, | ||
+ | print(df.loc[3: | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | # Accès aux cases par l' | ||
+ | print(df.iloc[3]) | ||
+ | print(df.iloc[3: | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | print(df[df.AGE > 80]) | ||
+ | </ | ||
+ | |||
+ | **Entrer des valeurs** | ||
+ | |||
+ | |||
+ | < | ||
+ | df2 = df.copy() | ||
+ | df2[' | ||
+ | print(df2) | ||
+ | </ | ||
+ | |||
+ | |||
+ | < | ||
+ | print (df2.shape) | ||
+ | |||
+ | # Eliminer les lignes avec un champs quelconque indéfini | ||
+ | df2 = df2.dropna(how=' | ||
+ | print (df2.shape) | ||
+ | |||
+ | # Remplacer les valeurs manquantes par 5 | ||
+ | print (df2.fillna(value=5)) | ||
+ | </ | ||
+ | |||
+ | |||
+ | < | ||
+ | print (pd.isnull(df2)) | ||
+ | </ | ||
+ | |||
+ | **Calculs simples** | ||
+ | |||
+ | < | ||
+ | print (df.mean()) | ||
+ | print( df.mean(1)) | ||
+ | </ | ||
+ | |||
+ | **Histograms** | ||
+ | |||
+ | < | ||
+ | # Histogramme des types de dommages | ||
+ | s = df.INJ_SEV.value_counts() | ||
+ | print(s) | ||
+ | |||
+ | </ | ||
+ | |||
+ | < | ||
+ | s.hist() | ||
+ | |||
+ | print (s.index, s.values) | ||
+ | p = pd.Series(s.index, | ||
+ | print (p) | ||
+ | p.hist() | ||
+ | |||
+ | plt.hist( s.values) | ||
+ | plt.show() | ||
+ | </ | ||
+ | |||
+ | **Merge jointure** | ||
+ | |||
+ | < | ||
+ | # 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[' | ||
+ | passengers = passengers[[' | ||
+ | new_data = pd.merge (drivers, passengers, on=[' | ||
+ | print(new_data.head()) | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | # L' | ||
+ | # on peut grouper sur plusieurs attributs avec [' | ||
+ | print(df.groupby(' | ||
+ | </ | ||
+ | |||
+ | **Input/ | ||
+ | |||
+ | < | ||
+ | df.to_csv(' | ||
+ | !ls | ||
+ | pd.read_csv(' | ||
+ | </ | ||
+ | |||
+ | ==== Pour aller plus loin ==== | ||
+ | |||
+ | Tutoriel : | ||
+ | * {{http:// | ||
+ | |||
+ | Données : | ||
+ | * {{https:// | ||
+ | |||
+ | ==== Données supplémentaires ==== | ||
+ | * {{https:// | ||
+ | * {{https:// | ||
+ | * {{https:// | ||
+ | * {{https:// | ||
+ | |||