Académique Documents
Professionnel Documents
Culture Documents
Pandas est un package Python populaire pour la science des données, et pour une bonne raison: il offre des
structures de données puissantes, expressives et flexibles qui facilitent la manipulation et l'analyse des
données, entre autres. Le DataFrame est l'une de ces structures.
Ceux qui sont familiers avec R connaissent la data frame comme un moyen de stocker des données dans
des grilles rectangulaires qui peuvent facilement être vues. Chaque ligne de ces grilles correspond aux
mesures ou aux valeurs d'une instance, tandis que chaque colonne est un vecteur contenant des données
pour une variable spécifique. Cela signifie que les lignes de données n'ont pas besoin de contenir, mais
peuvent contenir, le même type de valeurs: elles peuvent être numériques, caractères, logiques, etc.
Désormais, les DataFrames en Python sont très similaires: ils sont fournis avec la bibliothèque Pandas et ils
sont définis comme des structures de données étiquetées bidimensionnelles avec des colonnes de types
potentiellement différents.
En général, vous pourriez dire que le Pandas DataFrame se compose de trois composants principaux: les
données, l'index et les colonnes.
Avec une définition élargie, les données peuvent être contenu dans :
un Pandas DataFrame
une Pandas Series : un tableau étiqueté unidimensionnel capable de contenir n'importe quel type
de données avec des étiquettes d'axe ou un index. Un exemple d'objet Series est une colonne d'un
DataFrame.
NumPy ndarray
Outre les données, vous pouvez également spécifier les noms d'index et de colonne de votre DataFrame.
L'index, d'une part, indique la différence entre les lignes, tandis que les noms de colonnes indiquent la
différence entre les colonnes. Vous verrez plus tard que ces deux composants du DataFrame vous seront
utiles lorsque vous manipulerez vos données.
Pour utiliser des pandas, vous commencerez généralement par la ligne de code suivante. (On suppose que
numpy est déjà importé, sinon "import numpy as np" )
import pandas as pd
3.1 Creation des données
3.1.1 DataFrame
Un DataFrame est une table. Il contient un tableau d'entrées individuelles, dont chacune a une certaine
valeur. Chaque entrée correspond à une ligne (ou enregistrement) et une colonne.
Yes No
0 50 131
1 21 2
Dans cet exemple, l'entrée «0, No» a la valeur de 131. L'entrée «0, Yes» a une valeur de 50 et ainsi de suite
Les entrées DataFrame ne sont pas limitées aux entiers. Par exemple, voici un DataFrame dont les valeurs
sont des chaînes:
pd.DataFrame({'Bob': ['I liked it.', 'It was awful.'], 'Sue': ['Pretty good.',
'Bland.']})
Bob Sue
Nous utilisons le constructeur pd.DataFrame () pour générer ces objets DataFrame. La syntaxe pour en
déclarer un nouveau est un dictionnaire dont les clés sont les noms de colonnes (Bob et Sue dans cet
exemple), et dont les valeurs sont une liste d'entrées. C'est la manière standard de construire un nouveau
DataFrame, et celui que vous êtes le plus susceptible de rencontrer.
Le constructeur dictionnaire-liste attribue des valeurs aux étiquettes de colonne, mais utilise simplement un
nombre croissant de 0 (0, 1, 2, 3, ...) pour les étiquettes de ligne. Parfois, c'est correct, mais souvent, nous
voudrons attribuer ces étiquettes nous-mêmes.
Une liste des étiquettes de ligne utilisées dans un DataFrame est connue sous le nom d'index. Nous pouvons
lui attribuer des valeurs en utilisant un paramètre d'index dans notre constructeur:
Bob Sue
3.1.2 Series
Une série, en revanche, est une séquence de valeurs de données. Si un DataFrame est une table, une série
est une liste. Et en fait, vous pouvez en créer une avec rien de plus qu'une liste:
pd.Series([1, 2, 3, 4, 5])
Output:
0 1
1 2
2 3
3 4
4 5
dtype: int64
Une série est une seule colonne d'un DataFrame. Vous pouvez donc attribuer des valeurs de colonne à la
série de la même manière qu'auparavant, à l'aide d'un paramètre d'index. Cependant, une série n'a pas de
nom de colonne, elle n'en possède qu'un seul name :
2015 Sales 30
2016 Sales 35
2017 Sales 40
Name: Product A, dtype: int64
La série et le DataFrame sont intimement liés. Il est utile de penser qu’un DataFrame n’est en fait qu’un
ensemble de séries «collées ensemble».
Il est pratique de pouvoir créer un DataFrame ou une série à la main. Mais, la plupart du temps, nous ne
créerons pas nos propres données à la main. Nous travaillerons plutôt avec des données qui existent déjà.
Les données peuvent être stockées dans un certain nombre de formes et de formats différents. Le plus
élémentaire d'entre eux est de loin le modeste fichier CSV. Lorsque vous ouvrez un fichier CSV, vous obtenez
quelque chose qui ressemble à ceci:
Un fichier CSV est donc un tableau de valeurs séparées par des virgules, d'où le nom Comma-Separated
Values", or CSV.
samples = pd.read_csv("sample.csv")
wine_reviews.shape
wine_reviews.head()
Les informations d'étiquetage des axes dans les objets pandas servent à plusieurs fins:
Identifie les données (c'est-à-dire fournit des métadonnées) à l'aide d'indicateurs connus, importants
samples
En Python, nous pouvons accéder à la propriété d'un objet en y accédant en tant qu'attribut. Un objet
book , par exemple, peut avoir une propriété title , à laquelle nous pouvons accéder en appelant
book.title . Les colonnes d'un pandas DataFrame fonctionnent à peu près de la même manière.
Par conséquent, pour accéder à la propriété country de samples, nous pouvons utiliser:
samples.country
output:
0 Italy
1 Portugal
...
129969 France
129970 France
Name: country, Length: 129971, dtype: object
Si nous avons un dictionnaire Python, nous pouvons accéder à ses valeurs en utilisant l'opérateur
d'indexation ( [] ). Nous pouvons faire la même chose avec des colonnes dans un DataFrame:
reviews['country']
Output:
0 Italy
1 Portugal
...
129969 France
129970 France
Name: country, Length: 129971, dtype: object
Ce sont les deux façons de sélectionner une série spécifique dans un DataFrame. Aucun d'eux n'est plus ou
moins syntaxiquement valide que l'autre, mais l'opérateur d'indexation [] a l'avantage de pouvoir gérer les
noms de colonnes avec des caractères réservés.
Une série de pandas ne ressemble-t-elle pas à un dictionnaire sophistiqué? C'est à peu près le cas, il n'est
donc pas surprenant que, pour explorer une valeur spécifique unique, nous n'utilisions qu'une fois de plus
l'opérateur d'indexation []:
samples['country'][0]
Output:
'Italy'
pandas a ses propres opérateurs d'accesseurs, loc et iloc . Les deux loc et iloc sont row-first, column-
second. C'est le contraire de ce que nous faisons en Python natif, qui est column-first, row-second.
sélectionner des données en fonction de leur position numérique dans les données. iloc suit ce
paradigme.
Pour sélectionner la première ligne de données dans un DataFrame, nous pouvons utiliser ce qui suit:
samples.iloc[0]
Output:
country Italy
description Aromas include tropical fruit, broom, brimston...
...
variety White Blend
winery Nicosia
Name: 0, Length: 13, dtype: object
Pour obtenir une colonne avec iloc, nous pouvons faire ce qui suit:
samples.iloc[:, 0]
Output:
0 Italy
1 Portugal
...
129969 France
129970 France
Name: country, Length: 129971, dtype: object
Pour sélectionner la colonne de pays uniquement à partir de la première, deuxième et troisième lignes,
nous ferions:
samples.iloc[:3, 0]
Output:
0 Italy
1 Portugal
2 US
Name: country, dtype: object
samples.iloc[1:3, 0]
Output:
1 Portugal
2 US
Name: country, dtype: object
reviews.iloc[[0, 1, 2], 0]
Output:
0 Italy
1 Portugal
2 US
Name: country, dtype: object
Enfin, il convient de savoir que les nombres négatifs peuvent être utilisés dans la sélection.
samples.iloc[-5:]
Dans ce paradigme, c'est la valeur de l'indice de données, et non sa position, qui compte.
Par exemple:
samples.loc[0, 'country']
Output:
'Italy'
iloc est conceptuellement plus simple que loc car il ignore les indices de l'ensemble de données.
Lorsque nous utilisons iloc , nous traitons l'ensemble de données comme une grande matrice (une liste
de listes), dans laquelle nous devons indexer par position. loc , en revanche, utilise les informations
contenues dans les indices pour faire son travail. Étant donné que votre ensemble de données a
généralement des indices significatifs, il est généralement plus facile de faire les choses en utilisant loc à
la place
samples.country == 'Italy'
Output:
0 True
1 False
...
129969 False
129970 False
Name: country, Length: 129971, dtype: bool
Cette opération a produit une série de valeurs booléennes Vrai / Faux en fonction du pays de chaque
enregistrement. Ce résultat peut ensuite être utilisé à l'intérieur de loc pour sélectionner les données
pertinentes:
samples.loc[samples.country == 'Italy']
Nous pouvons utiliser l'esperluette (&) ou le tube (|) pour réunir les deux questions:
Nous avons également trois méthodes qui nous aident à sélectionner les données
#sélectionner des vins uniquement d'Italie ou de France:
samples.loc[samples.country.isin(['Italy', 'France'])]
#Ces méthodes vous permettent de mettre en évidence les valeurs qui sont (ou ne
sont pas) vides (NaN).
samples.loc[samples.price.isnull()]
samples.loc[samples.price.notnull()]
En plus de l'assignation classique d'une valeur à une position spécifique, vous pouvez attribuer une valeur
constante
reviews['critic'] = 'everyone'
reviews['critic']
Output:
0 everyone
1 everyone
...
129969 everyone
129970 everyone
Name: critic, Length: 129971, dtype: object
Output:
0 129971
1 129970
...
129969 2
129970 1
Name: index_backwards, Length: 129971, dtype: int64
3.6 Dtypes
Le type de données d'une colonne dans un DataFrame ou une Series est appelé dtype
samples.price.dtype
dtype('float64')
samples.dtypes
country object
description object
...
variety object
winery object
Length: 13, dtype: object
Les valeurs manquantes des entrées reçoivent la valeur NaN, abréviation de "Not a Number". Pour des
raisons techniques, ces valeurs NaN sont toujours de type float64 .
samples[pd.isnull(samples.country)]
Le remplacement des valeurs manquantes est une opération courante. Pandas fournit une méthode très
pratique pour résoudre ce problème: fillna() . Par exemple, nous pouvons simplement remplacer
chaque NaN par un "Inconnu":
reviews.region_2.fillna("Unknown")
Output:
0 Unknown
1 Unknown
...
129969 Unknown
129970 Unknown
Name: region_2, Length: 129971, dtype: object
Alternativement, nous pouvons avoir une valeur non nulle que nous aimerions remplacer.
samples.taster_twitter_handle.replace("valueToReject", "newValueToKeep")
4 Traitement des données avec Pandas
Toute les méthodes dans cette section sont applicables à la fois pour une série et une dataframe
samples.points.describe()
Output:
count 129971.000000
mean 88.447138
...
75% 91.000000
max 100.000000
Name: points, Length: 8, dtype: float64
Par exemple, pour voir la moyenne des points attribués, nous pouvons utiliser la fonction mean ():
samples.points.mean()
Output:
88.44713820775404
Pour voir une liste de valeurs uniques, nous pouvons utiliser la fonction unique ():
samples.taster_name.unique()
Output:
samples.taster_name.value_counts()
Output:
Map est un terme, emprunté aux mathématiques, pour une fonction qui prend un ensemble de valeurs et
les «mappe» à un autre ensemble de valeurs. En science des données, nous avons souvent besoin de créer
de nouvelles représentations à partir de données existantes ou de transformer des données. Maps sont ce
qui gère ce travail, ce qui les rend extrêmement importantes pour faire votre travail!
Par exemple, supposons que nous voulions remanier les scores moyens des vins reçus à 0. Nous pouvons le
faire comme suit:
sample_points_mean = samples.points.mean()
samples.points.map(lambda p: p - sample_points_mean)
Output:
0 -1.447138
1 -1.447138
...
129969 1.552862
129970 1.552862
Name: points, Length: 129971, dtype: float64
La fonction que vous transmettez à map () doit attendre une valeur unique de la série et renvoyer une
version transformée de cette valeur. Map () renvoie une nouvelle série dans laquelle toutes les valeurs ont
été transformées par votre fonction.
apply () est la méthode équivalente si nous voulons transformer un DataFrame entier en appelant une
méthode personnalisée sur chaque ligne(avec axis='columns' sinon axis='index' pour transformer chaque
colonne).
sample_points_mean = samples.points.mean()
def remean_points(row):
row.points = row.points - review_points_mean
return row
samples.apply(remean_points, axis='columns')
“
Notez que map () et apply () renvoient respectivement de nouveaux Series et DataFrames
transformés. Ils ne modifient pas les données d'origine sur lesquelles ils sont appelés
Nous pouvons aussi proposer une solution comme la façon du traitement de matrice dans Numpy :
sample_points_mean = samples.points.mean()
samples.points - sample_points_mean
Output: