TP 1 : Les tableaux de données

Un data frame est un tableau de données. En général, les données à analyser sont contenues dans un tel tableau de données. Leur manipulation est un pré-equis avant toute analyse, représentation ou exploitation des données. Ce TP propose une introduction aux éléments essentiels des tableaux de données.
Ce TP et tous les suivants peuvent être réalisés au choix en Python ou en R. Chaque étudiant choisit le langage dans lequel il souhaite travailler. Je conseille d'utiliser R.
Dans tous les TPs, les explications spécifiques à Python et à R seront données dans une table comme celle ci-dessous :

Python

En Python, on utilisera les tableaux de données définis dans le paquetage pandas. Les tableaux de données sont disponibles dans le paquetage pandas. Il faut donc l'importer pour réaliser les manipulations. Il est courant de le surnommer pd en le chargeant par la commande import pandas as pd.
La documentation sur pandas est disponible en ligne.



R

En R, les tableaux de données sont l'un des types d'objets prédéfinis dans le langage. Aucune paquetage n'est nécessaire pour les utiliser.
Rappelons qu'en R, la documentation est immédiatement accessible par la commande ?nom-de-la-fonction. En particulier, aucun accès à Internet n'est nécessaire pour accéder à la documentation qui est de très grande qualité.
Ce TP suppose une connaissance minimale de R et il ne pose dans ce cas aucune difficulté. En cas de besoin, voir ce TP d'introduction à R.

Ce TP doit être terminé avant la deuxième séance de cours.

Introduction

Un tableau de données est constitué d'un ensemble de lignes et de colonnes. Chaque ligne correspond à une donnée, chaque colonne correspond à un attribut. À l'intersection d'une ligne avec une colonne, on trouve la valeur de l'attribut pour la donnée. Si celle-ci est inconnue, on utilise généralement la valeur NA qui signifie Non Available, quoique cette convention ne soit pas toujours bien respectée.
À noter que Python ne gère pas bien les NAs et les valeurs de ce type (par exemple, Python ne distingue pas les valeurs manquantes NA des valeurs numériques incorrectes, connues en informatique sous le nom de NaN qui signifie Not A Number). Cela peut sembler anecdotique mais c'est très ennuyeux que Python ne gère pas correctement ces valeurs spéciales. R le fait de manière rigoureuse en définissant correctement ces valeurs spéciales et en fournissant les outils pour les manipuler.

Manipulations

Chargement du contenu d'un tableau de données

Les données d'un tableau sont généralement stockées dans un fichier. En préalable à toute analyse, les données doivent être chargées dans un data frame. Il existe de multiples formats pour stocker les données d'un tableau dans un fichier. Quand il s'agît de données simples, l'un des plus répandus est un fichier au format csv.
Comme dans un tableau de données, dans un fichier csv, chaque ligne correspond à une donnée et chaque colonne à un attribut. Sur une ligne, les valeurs des attributs sont généralement séparées par une virgule. Nénamoins, il est tout à fait possible d'utiliser un autre caractère pour séparer les données. La première ligne du fichier csv peut indiquer le nom des attributs ; elle est optionnelle. Si elle est présente, cette ligne se nomme un en-tête, header en anglais.
Dans ce TP, nous allons utiliser un jeu de données qui représente la composition d'olives en différentes molécules ainsi que leur origine géographique. Le fichier se trouve à cette url : https://philippe-preux.codeberg.page/ensg/miashs/datasets/olives.csv.

Python

La fonction pandas qui charge un fichier csv est read_csv.

R

En R, on utilise la fonction read.csv ().

À faire : en s'aidant si nécessaire de la documentation, charger ce fichier dans un objet dénommé olives.

Remarque pratique importante : il faut garder à l'esprit qu'un fichier csv peut être édité avec un éditeur de textes. Il n'est pas rare que l'on doive le modifier avant de pouvoir le charger dans Python ou pour en simplifier le traitement dans Python ; il n'est pas rare non plus que ces modifications soient plus faciles à réaliser dans un éditeur de textes que dans Python ou R.

Premiers pas

Une fois un jeu de données chargé, les toutes premières choses à faire consistent à simplement inspecter son contenu :

À faire :

Python
>>> olives.head (n=5)
     Unnamed: 0  region  area  ...  linolenic  arachidic  eicosenoic
0  North-Apulia       1     1  ...         36         60          29
1  North-Apulia       1     1  ...         31         61          29
2  North-Apulia       1     1  ...         31         63          29
3  North-Apulia       1     1  ...         50         78          35
4  North-Apulia       1     1  ...         50         80          46

[5 rows x 11 columns]




R
> head (olives)
             X region area palmitic palmitoleic stearic oleic linoleic
1 North-Apulia      1    1     1075          75     226  7823      672
2 North-Apulia      1    1     1088          73     224  7709      781
3 North-Apulia      1    1      911          54     246  8113      549
4 North-Apulia      1    1      966          57     240  7952      619
5 North-Apulia      1    1     1051          67     259  7771      672
6 North-Apulia      1    1      911          49     268  7924      678
  linolenic arachidic eicosenoic
1        36        60         29
2        31        61         29
3        31        63         29
4        50        78         35
5        50        80         46
6        51        70         44
Python

Utiliser l'attribut shape du tableau de données.


R

Utiliser la fonction dim() sur le tableau de données pour obtenir le nombre de lignes et de colonnes, la fonction nrow() pour obtenir uniquement le nombre de lignes, et la fonction ncol() pour obtenir uniquement le nombre de colonnes.

Python

utiliser la méthode list() ou l'attribut columns du tableau de données.

R

Utiliser la fonction names().

Python
olives.rename (columns = {"Unnamed: 0": "Area Name"}, inplace = True)

L'argument columns = {"Unnamed: 0": "Area Name"} indique avec un dictionnaire la (ou les) colonne(s) à renommer.

R
names (olives) [1] <- "Area.Name"


Accès aux éléments d'un tableau de données

Pour analyser un jeu de données, il faut accéder aux valeurs des attributs des données. En particulier, il faut accéder à la valeur des attributs qui nous intéresse, pour les données qui nous intéressent.

Python

Pour cela, on utilise les attributs loc [] et iloc [].
iloc [] permet de sélectionner des lignes ou des colonnes par leurs indices. loc() est beaucoup plus général et permet de sélectionner des lignes ou des colonnes en indiquant un nom ou en les sélectionnant selon un critère.

À faire :

  • Accès à la donnée numéro 27 : olives.iloc [27].
  • Accès aux données numéro 20 à 27 : olives.iloc [20:28].
  • Accès à l'attribut 5 de la donnée 27 : olives.iloc [27,5] (à comparer à ce que vous avez obtenu ci-dessus).
    On peut aussi accéder à l'attribut via son nom : olives.loc [27,"stearic"].
    ou encore olives.stearic [27].
    ou encore, si on ne connait pas le nom du 5è attribut, on peut aussi écrire : olives.loc [27, list (olives)[5]].
    Ces quatre lignes doivent donner le même résultat.
  • Pour accéder à la valeur de l'attribut pour toutes les données : utiliser la notation : : olives.stearic [:]
    ou autre variante : olives.stearic.values.
  • Je vous laisse trouver comment on accède à l'attribut 5 des données numérotées 20 à 28.
  • Je vous laisse trouver comment on accède aux attributs 3 à 6 des données numérotées 20 à 28.






R

Si vous connaissez R, vous savez déjà tout ce qui indiqué ci-dessous.
On indice simplement le tableau de données avec une notation de la forme tableau.de.données [numéros.de.ligne, numéros.de.colonnes].
On peut spécifier un seul numéro de ligne ou de colonne, par exemple [3, 6] permet d'accéder à la donnée située en 3è ligne, 6è colonne.
Si on omet le numéro de colonnes, on accède à toutes les colonnes de la ligne (par exemple [3, ]).
Si on omet le numéro de lignes, on accède à toutes les lignes de la colonne (par exemple [, 6]).
On peut indiquer un ensemble de lignes ou de colonnes avec une notation de la forme c (3, 7, 9, 18, 2, 1) ou encore 3:6.
Et on peut sélectionner des lignes ou des colonnes répondant à des critères logiques avec la fonction which(), fonction tellement puissante, et très simple d'utilisation, qu'il faut absolument la maîtriser.

À faire :

  • Accès à la donnée numéro 27 : olives [27,].
  • Accès aux données numéro 20 à 27 : olives [20:27,].
  • Accès à l'attribut 5 de la donnée 27 : olives [27,5] (à comparer à ce que vous avez obtenu ci-dessus).
    On peut aussi accéder à l'attribut via son nom : olives [27,"stearic"],
    ou olives$stearic [27],
    ou encore, si on ne connait pas le nom du 5è attribut, on peut aussi écrire : olives [27, names (olives)[5]].
    Ces quatre lignes doivent donner le même résultat.
  • Je vous laisse trouver comment on accède à l'attribut 5 des données numérotées 20 à 28.
  • Je vous laisse trouver comment on accède aux attributs 3 à 6 des données numérotées 20 à 28.

Quelques opérations simples

À faire : au besoin en consultant la documentation, effectuer les opérations suivantes :

Mêmes choses pour les attributs 3 à 6.

Accès aux éléments d'un tableau de données, la suite

À faire :

Python

Pour les attributs numériques, on peut utiliser les méthodes de la bibliotèque numpy. Par exemple, pour calculer la valeur moyenne de l'attribut 5, on peut aussi écrire : np.mean (olives.iloc [:,5]) (en supposant que vous avez importé numpy en le renommant np).

À faire : répondre aux deux questions précédentes en utilisant des méthodes de la bibliothèque numpy.

R

On utilise les fonctions which.min() et which.max.

À faire : répondre aux deux questions précédentes.



Attributs catégoriques

Un attribut catégorique, ou nominal, est un attribut dont la valeur est prise parmi un ensemble fixé de valeurs possibles. Par exemple une couleur parmi jaune, vert, rouge, orange, violet. Ainsi, l'attribut 0 est un attribut catégorique qui indique la région de provenance de l'olive. De même, malgré les apparences qui peuvent faire croire que les attributs 1 et 2 sont numériques, ce sont en fait des attributs catégoriques : l'attribut 2 est simplement un numéro correspondant à la valeur de l'attribut 0. Quant à l'attribut 1, c'est une valeur 1, 2 ou 3 qui indique grossiérement la zone géographique : sud de l'Italie (1), Sardaigne (2), nord de l'Italie (3).

Pour éviter des erreurs malencontreuses comme calculer la valeur moyenne d'un attribut catégorique, il faut indiquer explicitement les attributs catégoriques.

Python

Pour cela, on fait : olives ["Area Name"] = olives ["Area Name"].astype("category").

R

Pour cela, on utilise la fonction factor() : olives$Area.Name <- factor (olives$Area.Name)

Vérifier maintenant que vous ne pouvez plus calculer la moyenne de cet attribut.

Remarque : les attributs catégoriques sont très mal gérés en Python et ils le sont très bien en R. C'est une faiblesse majeure de Python pour la fouille de données alors que les attributs catégoriques sont omniprésents dans les jeux de données. Ce mauvais traitement pourra entraîner des résultats faux en Python qui confond attribut nominal et attribut quantitatif, là où R ne fera aucune erreur.

À faire :

Pour les attributs catégoriques, il est intéressant d'obtenir la liste des valeurs présentes dans le jeu de données et également le nombre de données dans chaque catégorie.

À faire :

Python
  • Pour obtenir la liste des valeurs, on utilise la méthode unique().
  • Pour obtenir le décompte de données correspondant à chaque valeur d'un attribut catégorique, on utilise la méthode value_counts().
  • Appliquez ces deux méthodes aux attributs catégoriques du jeu de données olives.
R
  • Pour obtenir la liste des valeurs, on utilise la méthode levels().
  • Pour obtenir le décompte de données correspondant à chaque valeur d'un attribut catégorique, on construit une table de contigence avec la fonction table().
  • Appliquez ces deux méthodes aux attributs catégoriques du jeu de données olives.

Ajout et retrait d'un attribut (une colonne) à un tableau de données

On a souvent besoin d'ajouter ou de retirer un attribut à un jeu de données. On procède comme suit.
On suppose que v est un vecteur contenant autant d'éléments qu'il y a de données dans le tableau de données df. Pour ajouter un nouvel attribut, on fait :

Python

df ["nouvel attribut"] = v

R

df ["nouvel.attribut"] <- v

Pour retirer un attribut nommé a, on fera ainsi :

Python

df.drop (columns = ["a"])
ou
df.drop (["a"], axis = 1)

R

df$a <- NULL