introduction sur les tables de données¶
lecture d’une table de données¶
format CSV¶
la librairie de data-science¶
on importe pandas¶
# le code
import pandas as pd
pd.__version__'3.0.6'lecture d’un fichier csv¶
# le code
df = pd.read_csv('data/titanic.csv')
type(df)pandas.DataFrame# pour afficher les premières lignes
# à votre avis, comment on voit les dernières lignes ?
df.head(2)lecture d’un fichier excel¶
# le code
# %pip install openpyxl# le code
df1 = pd.read_excel('data/titanic.xlsx')description rapide de la table des données¶
# le code
# pas besoin de 6 chiffres après la virgule
pd.options.display.precision = 2
df.describe()df[['Age', 'Fare']].describe()# le code
df.describe(include='all')# le code
df['Age'].describe()count 714.00
mean 29.70
std 14.53
min 0.42
25% 20.12
50% 28.00
75% 38.00
max 80.00
Name: Age, dtype: float64les index et indices des tables¶
si vous préférez: les noms et rangs des tables
les deux termes index et indice sont très proches et peuvent prêter à confusion
aussi si vous préférez vous pouvez pour l’instant les assimiler à:
index est synonyme de nom; par exemple quand j’écris
df['Survived'],'Survived'est un index (dans les colonnes)indice est synonyme de rang; je pourrais aussi écrire à la place
df[1], comme on parle de la deuxième colonne; ici1est un indice
la notion d’index¶
index des colonnes¶
# le code
df.columnsIndex(['PassengerId', 'Survived', 'Pclass', 'Name', 'Sex', 'Age', 'SibSp',
'Parch', 'Ticket', 'Fare', 'Cabin', 'Embarked'],
dtype='str')df.columns[0]'PassengerId'accès aux colonnes avec df[]¶
df['Age'].head(4)0 27.0
1 31.0
2 25.0
3 NaN
Name: Age, dtype: float64# type Series
type(df['Age'])pandas.Series# on peut aussi passer une liste de colonnes
# auquel cas on récupère une dataframe
df[['Age', 'Sex']].head()Copy on Write (CoW)¶
Pour optimiser cela (et ne pas passer son temps à recopier dans tous les sens), pandas utilise un pattern de programmation qui s’appelle le Copy on Write
Voyons ça sur un exemple: on part d’une grosse table et
on extrait une série en faisant donc
df[colname]immédiatement après on va écrire dans la série - ici on modifie la première valeur
puis enfin on va modifier la deuxième valeur
vous allez voir que
pour la première opération:
d’après ce qui précède cette opération devrait prendre un peu du temps puisqu’il faut tout recopier; vous allez voir que ce n’est pas le caspar contre la seconde:
elle va prendre davantage de temps ! en fait c’est à ce moment-là seulement que la copie est effectivement faite !et la troisième opération: elle est rapide à nouveau; on a déjà fait la copie, du coup ça prend un temps “normal”
et le résultat final, c’est qu’à la fin de tout ça, notre dataframe n’est pas modifiée !!
et c’est normal, car on a modifié une copie de nos données, pas la dataframe...
# a simple helper function to create a big table
def big_table(N):
df = pd.DataFrame({'n': range(1, N + 1)})
df['square'] = df['n'] ** 2
return df
big = big_table(100_000)
big.head(3)%%time
# 1. on extrait un bout de la dataframe
# ce qui nous renvoie une copie
# ça devrait donc prendre un peu du temps
# mais en fait non !
series = big['square']CPU times: user 204 μs, sys: 0 ns, total: 204 μs
Wall time: 236 μs
%%time
# 2. on modifie la première valeur
# c'est lent !
# c'est parce que, comme c'est la première qu'on cherche à écrire, on copie d'abord
# Copy before Write - en + court, Copy on Write
%timeit series[0] = 1_000_0003.83 μs ± 220 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
CPU times: user 3.22 s, sys: 6.74 ms, total: 3.23 s
Wall time: 3.24 s
%%time
# 3. on modifie la seconde valeur
# cette fois c'est rapide, car plus besoin de faire la copie
series[1] = 1_000_001CPU times: user 0 ns, sys: 249 μs, total: 249 μs
Wall time: 259 μs
# EPILOGUE
# si vous ne devez retenir qu'une seule chose, c'est ceci:
# la dataframe d'origine N'A PAS été changée:
big.head(3)accès aux colonnes avec df.¶
# le code
# on peut aussi accéder à une colonne par un attribut
# qui est une notation plus lisible
df.Age0 27.00
1 31.00
2 25.00
3 NaN
4 24.00
...
886 47.00
887 30.00
888 36.00
889 22.00
890 0.83
Name: Age, Length: 891, dtype: float64type des colonnes pandas.Series¶
# le code
type(df['Age'])pandas.Seriesindexer les lignes¶
# le code - option 1.
df = pd.read_csv('data/titanic.csv', index_col='PassengerId')# le code - option 2.
df = pd.read_csv('data/titanic.csv')
# la table avant
df.head(1)# la table après
# remarquez que 'PassengerId'
# n'est plus présenté de la même manière
df = df.set_index('PassengerId')
df.head(1)# le code - option 3
# la méthode set_index avec son paramètre inplace à True
# modifie directement la table sans renvoyer une nouvelle dataframe
df = pd.read_csv('data/titanic.csv')
df.set_index('PassengerId', inplace=True)
df.head(1)une série aussi possède un index¶
# le code
df = pd.read_csv('data/titanic.csv', index_col='PassengerId')
df['Name']PassengerId
552 Sharp, Mr. Percival James R
638 Collyer, Mr. Harvey
499 Allison, Mrs. Hudson J C (Bessie Waldo Daniels)
261 Smith, Mr. Thomas
395 Sandstrom, Mrs. Hjalmar (Agnes Charlotta Bengt...
...
463 Gee, Mr. Arthur H
287 de Mulder, Mr. Theodore
326 Young, Miss. Marie Grice
396 Johansson, Mr. Erik
832 Richards, Master. George Sibley
Name: Name, Length: 891, dtype: str# ici on obtient bien la première ligne !
# quand on indexe une Series,
# c'est par l'index (552)
# et non pas par l'indice qui ici serait 0
df['Name'][552]'Sharp, Mr. Percival James R'différence entre index et indice¶
l’index des lignes¶
résumé à propos des types DataFrame et Series¶
forme et dimension de la table¶
# le code
df = pd.read_csv('data/titanic.csv', index_col='PassengerId')
print(df.shape)
print(df.ndim)(891, 11)
2
exercice basique¶
Le fichier data/petit-titanic.csv contient les 10 premières lignes de passagers
Attention ce n’est pas exactement le même format que data/titanic.csv
# pour voir le contenu du fichier
%cat data/petit-titanic.csv
# remarquez qu'on peut aussi voir ce contenu en Python pur
#with open("data/petit-titanic.csv") as f:
# for line in f:
# print(line, end="")552;0;2;Sharp, Mr. Percival James R;male;27.0;0;0;244358;26.0;;S
638;0;2;Collyer, Mr. Harvey;male;31.0;1;1;C.A. 31921;26.25;;S
499;0;1;Allison, Mrs. Hudson J C (Bessie Waldo Daniels);female;25.0;1;2;113781;151.55;C22 C26;S
261;0;3;Smith, Mr. Thomas;male;;0;0;384461;7.75;;Q
395;1;3;Sandstrom, Mrs. Hjalmar (Agnes Charlotta Bengtsson);female;24.0;0;2;PP 9549;16.7;G6;S
811;0;3;Alexander, Mr. William;male;26.0;0;0;3474;7.8875;;S
758;0;2;Bailey, Mr. Percy Andrew;male;18.0;0;0;29108;11.5;;S
703;0;3;Barbara, Miss. Saiide;female;18.0;0;1;2691;14.4542;;C
406;0;2;Gale, Mr. Shadrach;male;34.0;1;0;28664;21.0;;S
641;0;3;Jensen, Mr. Hans Peder;male;20.0;0;0;350050;7.8542;;S
lisez le contenu de ce fichier avec les paramètres par défaut de
pandas.read_csv
affichez les 2 premières lignes avecdf.head()
voyez-vous les trois problèmes ?
essayez de les résoudre en lisant le help de la fonctionhelp(pd.read_csv)oupd.read_csv?
ou passez à la question 2 pour être aidé
# votre codepassez le bon séparateur à la méthode
pandas.read_csv
indiquez lui que l’entête ne contient pas la liste des noms des colonnes
passez-lui la liste des noms des colonnes puisqu’elles ne sont pas mentionnées dans le fichier (à récupérer plus haut)
spoiler
voyez notamment les paramètres sep et names
# votre codeappliquer la méthode
describeaux colonnesAgeetFare
(ou plus exactement à une dataframe qui contient ces colonnes)
# votre codeaffichez le nombre de colonnes et de lignes
# votre codeaffichez les index des colonnes et des lignes
# votre codemodifiez l’index des colonnes par la liste
columns = ['Identifiant', 'Survécu', 'Pclass',
'Nom', 'Genre', 'Age', 'SibSp', 'Parch',
'Ticket', 'Tarif', 'Cabine', 'Embarquement']# votre codemodifiez l’index des lignes par la colonne
'Identifiant'
# votre code