Post on 11-Sep-2018
Mineure « Data Science » Frédéric Pennerath
Plan de travail
• Introduction à Python (débutants)
• Exercice : prétraitement des données
– Installer vos machines.
• Voir le script d’installation pour Ubuntu sur la page du cours
(www.metz.supelec.fr/metz/personnel/pennerath/Cours/DataScience)
– Créer un compte sur challengedata.ens.fr
– Etudier les compétitions.
– Former des trinômes, choisir un challenge et s’y inscrire.
– Télécharger les données de la compétition
– Commencer à explorer / mettre en forme / visualiser avec Pandas
• A faire pour la prochaine fois :
– Regarder les tutoriels Numpy et Pandas référencés sur la page du cours:
Mineure « Data Science » Frédéric Pennerath
Le langage Python
Python 2 (2000) et Python 3 (2008)– Dans la lignée de Perl :
• Langage « script » : interprété, compilé à la volée en bytecode (fichiers .ypc)
• Faiblement typé (typage à l’exécution)
• Ramasse miette
• Types de base, listes, dictionnaires
• Programmation fonctionnelle (faible)
• Programmation orientée objet (faiblement typée)
• Introspection
– Apports par rapport à Perl :
• Syntaxe plus propre et très intuitive
• Grande richesse des bibliothèques
– Forces et faiblesses :
• Les plus : flexibilité, simplicité et rapidité de développement
• Les moins : relativement lent et gourmand en mémoire, peu robuste (plantage à l’exécution)
Mineure « Data Science » Frédéric Pennerath
Les interpréteurs Python
python : interpréteur de base Python (2.7 ou 3)
>> python3 interpréteur en ligne
>> python3 script.py exécution d’un script
(compilation en ligne)
IPython : interpréteur amélioré (2.7, ou 3)
>> ipython3
>> ipython3 script.py
>> ipython3 --matplotlib pour des affichages de courbes
Jupyter: feuilles de calcul intégrées dans une page html
>> jupyter notebook & (jadis ipython3 notebook)
Mineure « Data Science » Frédéric Pennerath
Implémentation Python :
objet, type et adresse
type(1) # builtins.int
isinstance(1, int) # True
type(True) # builtins.bool
type(1.) # builtins.float
type(1+1j) # builtins.complex
type("1") # builtins.str
type([ 1, 2]) # builtins.list
type(( 1, 2)) # builtins.tuple
type({ 1, 2}) # builtins.set
type({"1" : 1, 2 : "2" }) # builtins.dict
Toute valeur est un objet ayant un type
Type de v : type(v)
Tout objet d’un type T est dit instance de T.
id(1) # 10105824
id(1) # 10105824
id(3.14) # 140004852491320
id(3.14) # 140004852491344
Tout objet occupe une zone mémoire définie
par sa taille et son adresse.
Adresse de v : id(v)
Les valeurs usuelles (0, …, 256, True, False) sont
stockées au démarrage dans des objets
immuables.
Les autres valeurs sont stockées dans des objets
créés dynamiquement.
Mineure « Data Science » Frédéric Pennerath
Implémentation Python :
variable et immuabilité
a = [] ; id(a) # 140004852430088
b = a ; id(b) # 140004852430088
b.append(1) ; a # [1]
id(b) # 140004852430088
Un objet dont le type est muable est modifiable.
Une modification sur une variable dont l’objet est
muable ne change pas l’adresse contenue dans la
variable mais modifie le contenu de la mémoire
représentant l’objet pointé.
Attention aux effets de bord !
Exemples : list, set, dict
Un objet dont le type est immuable n’est pas
modifiable. Une modification appliquée à une
variable dont l’objet est immuable modifie l’adresse
contenue dans la variable, qui pointe maintenant sur
un nouvel objet égal à l’objet modifié.
Exemples : int, bool, float, complex, str, tuple
a = [] ; id(a) # 140004852430088
b = a ; id(b) # 140004852430088
Les variables Python stockent l’adresse de
l’objet, pas l’objet lui-même.
id(1) # 10105824
id(2) # 10105856
a = 1 ; b = a
id(a) # 10105824
id(b) # 10105824
a += 1
id(a) # 10105856
id(b) # 10105824
Mineure « Data Science » Frédéric Pennerath
Implémentation Python :
méthodes et attributs
complex.conjugate(1j) # -1j
1j. conjugate() # -1j
a = []
list.append(a,1) # [1]
a.append(2) # [1,2]
Un objet a des méthodes et des
attributs caractéristiques de son type.
Les méthodes et attributs sont les
membres d’un objet.
1j. imag # 1.0
Une méthode d’un objet o est une
fonction T.f(...) rattachée à son type T qui
prend o comme premier argument.
Une méthode T.f(o,…) peut être appelée
selon la syntaxe o.f(…)
Un attribut a d’un objet o est une variable
rattachée à o selon la syntaxe o.a
Certaines méthodes définissent des
opérateurs
L1 = [1]; L2 = [2]
L = L1 + L2
L = L1.__add__(L2)
L = list.__add__(L1,L2)
Mineure « Data Science » Frédéric Pennerath
Implémentation Python :
classe d’objets
Une classe est un type muable défini par
l’utilisateur avec ses méthodes et ses attributs.
class Complexe:
def __init__(self, r, i = 0):
self.reel = r
self.imag = i
def conjugue(self):
self.imag = -self.imag
def __str__(self):
return str(self.reel) + " + " + str(self.imag) + "i"
def __eq__(self, c):
if(not isinstance(c, Complexe)):
return False
return (self.reel == c.reel)
and (self.imag == c.imag)
c = Complexe(1,2) # Appel du constructeur
print(c) # 1 + 2i
c.conjugue()
c == Complexe(1,-2) # True
La méthode __init__ est le
constructeur appelé lors
de la création d’un objet de
la classe. Il définit les
attributs de l’objet
self désigne l’objet courant. self.reel et
self.imag sont ses attributs.
La méthode __str__ est
appelée pour convertir
l’objet en une chaîne de
caractères.
La méthode __eq__ est
appelée lorsque l’objet sert
d’opérande gauche à
l’opérateur == de
comparaison.
Mineure « Data Science » Frédéric Pennerath
Inspection et manipulation des valeurs
help(v) / help(t) : renvoie la liste des opérations du type de v ou du type t
>> help(1)
dir(v) / dir(t) : liste les attributs d’une valeur ou d’un type
>> dir(int)
sys.getsizeof(v) : renvoie le nombre d’octets mémoire occupés par la valeur v
>> sys.getsizeof(1) → 24
Complétion sous IPython
>> 10.(tab) →
10.bit_length 10.denominator 10.numerator
10.conjugate 10.imag 10.real
<nom T de type>(v) : convertit la valeur v en une valeur de type T (si cela a un sens)
>> float("-3.14"’) → -3.14
>> str(3.14) → ’-3.14’
print(v) : affiche la valeur v
Mineure « Data Science » Frédéric Pennerath
Opérations de base
Opérations numériques (int, long, float, complex) :
– Calcul de mod24−1
2, 3 : >> ((2 ** 4 – 1) / 2) % 3 → 1
– Calcul de Im1+𝑗
1+𝑗: >> ((1+1j) /(1+1j).conjugate()).imag → 1.0
– Module math : >> import math; dir(math)
Comparaisons (tout type) : ==, !=, <, >, <=, >=, cmp(x,y)
>> cmp("abc","baa") → -1
Mise à jour de variables : =,+=, -=, *=, …
Opérations et fonctions sur les chaînes :
>> infinitif = "programmer"; langage = "python".title()
>> forme = "je " + infinitif .strip("er" ) + "e en " + langage
>> mots = forme.split()
>> "-".join(mots)
>> len(forme); forme.index("en"); forme.replace("Python", "Perl")
Mineure « Data Science » Frédéric Pennerath
Les structures de contrôle
Les blocs d’instruction sont définis par indentation.
Remarques:
• Un bloc indenté ne peut être introduit qu’à la suite de « : » (if, while, def, etc)
• Faites attention à indenter un bloc de façon homogène (même nbr. de tab/espace)
Tests :
if condition1 :
…
elif condition2 :
…
else:
…
Boucles :
for x in range(min,max+1, step) :
…
while condition :
…
break # Sort de la boucle
continue # Passe à l’itération suivante
while not(fini()):
pass # Boucle vide
Exceptions :
try :
…
raise Exception("erreur !")
except Exception as e :
print("Error: {}"..format(e))
raise # Si on veut relancer l’exception
Mineure « Data Science » Frédéric Pennerath
Exercices
Exercice 1 : tests et boucles
Afficher la liste des nombres premiers compris 1 et n en testant s’il existe pour
chaque entier un diviseur.
Exercice 2 : listes
Même exercice avec le crible d’Eratosthène
Exercice 3 : dictionnaires et fichiers
Lire un fichier texte en entrée et écrire dans un fichier en sortie :
• Soit la liste des mots associés à leur fréquence
• Soit la liste des numéros des lignes où apparaissent un mot donné
Les paramètres seront passés en arguments de la ligne de commande.
Mineure « Data Science » Frédéric Pennerath
Les listes et les tuples
• Les listes (list) et tuples (tuple) sont des séquences non typées :
L = [1, "a"]; T = (True, L)
• Les listes sont en réalité des tableaux dynamiques (equiv. aux vecteurs de la STL)
• Les listes sont mutables, les tuples non.
• Les tuples servent souvent à renvoyer des résultats multiples depuis une fonction.
>> (a,b) = (1,2) → a = 1; b = 2
>> L = [1, 2, "a", [ 1.], False]
>> type(L) → list
>> L[0] → 1
>> L[-1] → False
>> L[2:4] → ['a', [1.0]]
>> L.pop() → False
>> L.pop(0) → 1
>> L.append(False) → [2, 'a', [ 1.], True]
>> sorted(L) → [True, 2, [1.0], 'a']
>> L = list(range(2,5)) → [2, 3, 4]
>> [x*2 for x in L] → [4, 6, 8]
>> [x*2 for x in L if x % 2 == 0] → [4, 8]
Mineure « Data Science » Frédéric Pennerath
Les dictionnaires
Les dictionnaires (dict) sont des tableaux associatifs (tables de hachage) non typés:
>> D={"a":1, 3: True}
>> D → {3: True, 'a': 1}
>> D["a"] → 1
>> D["b"] = 2 → {3: True, 'a': 1, 'b': 2}
>> D.keys() → ['a', 3, 'b']
>> D.values() → [1, True, 2]
>> D.pop(3) → True>> try:
entry = dictionary[word]
except KeyError:
raise Exception("Unknown word " + word)
Les ensembles (set) sont des dictionnaires sans valeurs :
>> S={"a", 3}
Les dictionnaires et listes peuvent s’imbriquer (création facilitée de graphes, etc) :
>> FdD = {"nom": "fouille de données", "vol" : 24}
>> SIR = {"nom": "SIR", "mineures" : [ FdD, …]}
>> FdD[’majeure’] = SIR
>> SIR['mineures'][0]['majeure'] == SIR → True
Mineure « Data Science » Frédéric Pennerath
Les fonctions
Liste d’arguments variable :
def test(*positionnels, **mots_cles):
print("positionnels = " + str(positionnels)
print("mots clés = " + str(mots_cles)
>> test(1,True, "a", a = 1, b = "b")
positionnels = (1, True, 'a')
mots clés = {'a': 1, 'b': 'b'}
Déclaration de fonction :
def phrase(mots, p = '.', s = ' '):
’’’Construit une phrase a partir de mots’’’
mots[0] = mots[0].title()
res = s.join(mots)
res += p
return res
Appel de fonction :
>> mots = ["ceci", "est", "un", "test"]
>> phrase(mots) → ‘Ceci est un test.'
>> phrase(mots,’;’,’-’) → 'Ceci-est-un-test;‘
>> phrase(mots, s=’-’) → 'Ceci-est-un-test.'
Mineure « Data Science » Frédéric Pennerath
Les scripts
• Fichier texte avec extension .py
• Exécution en ligne de commande : python script.py arg1 arg2 …
import sys
def phrase(mots, p = '.', s = ' '):
"""Creer une phrase a partir de mots
"""
mots[0] = mots[0].title()
res = s.join(mots)
res += p
return res
# Ici commence le code du main :
args = sys.argv # Arguments passés en ligne de commande
args.pop(0) # Elimine le nom du script
print(phrase(args))
Mineure « Data Science » Frédéric Pennerath
Exercices
Exercice 1 : tests et boucles
Afficher la liste des nombres premiers compris 1 et n en testant s’il existe pour
chaque entier un diviseur.
Exercice 2 : listes
Même exercice avec le crible d’Eratosthène
Exercice 3 : dictionnaires et fichiers
Lire un fichier texte en entrée et écrire dans un fichier en sortie :
• Soit la liste des mots associés à leur fréquence
• Soit la liste des numéros des lignes où apparaissent un mot donné
Les paramètres seront passés en arguments de la ligne de commande.
Mineure « Data Science » Frédéric Pennerath
Programmation fonctionnelle et fonctions lambda
Le type fonction
Les fonctions sont des valeurs dont les noms sont des variables :
>> def carre(x): return x*x
>> f = carre; f(2) → 4
>> carre = 1; carre(2) → TypeError: 'int' object is not callable
>> def map2(f, L):
return [f(x) for x in L]
>> map2(carre, range(1,5)) → [1, 4, 9, 16]
Fonctions lambda et paramétrisation d’algorithmes :
>> map(lambda x : x*x, range(1,5)); filter(lambda x : x%2 == 0, range(1,5))
>> L=[{"n" : 1, "m" : 3}, {"n" : 3, "m" : 2}, {"n" : 2, "m" : 1}]
>> sorted(L, key = lambda x: x["m"], cmp = lambda x,y: cmp(y,x))
→ [{'m': 3, 'n': 1}, {'m': 2, 'n': 3}, {'m': 1, 'n': 2}]
Mineure « Data Science » Frédéric Pennerath
Les itérables et les boucles
Itérable : object renvoyant un itérateur utilisé par les boucles for
>> for x in <iterable> : print(x)
Exemples d’énumérations:
D’une liste : >> for x in [1,2,3]: ...
D’un tuple : >> for x in (1,2,3): ...
D’une chaîne : >> for x in "abcd":
D’un ensemble : >> for x in {1,2,3}:
Des clés d’un dictionnaire : >> for x in {"a" : 1, "b" : 2, "c" : 3}:
Des valeurs d’un dictionnaire : >> for x in {"a" : 1, "b" : 2, "c" : 3}.values():
Des lignes d’un fichier texte >> for x in open(file= "fichier", mode = "r")
Listes par compréhension
>> [x ** 3 for x in range(1,10) ] // Equivalent à map
>> [x for x in range(1,10) if (x % 2 == 0) ] // Equivalent à filter
>> [x ** 3 for x in range(1,10) if (x % 2 == 0) ] // Map + Filter
>> [(i,j) for i in range(1,5) for j in range(1,i+1)] // double itération
>> [(i,j) for i in range(1,5) if(i % 2 == 0) for j in range(1,i+1)]
Mineure « Data Science » Frédéric Pennerath
Les fichiers
Accès en lecture:>> f = open(file=fileName, mode="r", encoding="utf-8", errors='replace')
>> for line in f:
>> ...
>> f.close()
Accès en écriture :
>> f = open(file=fileName, mode="w", encoding="utf-8")
>> print("passage à la ligne suivante", file = f)
>> print("sans saut de ligne", file = f, end = '')
>> f.close()
Enumérer les fichiers d’un répertoire :
>> from os import listdir
>> for fileName in listdir("."): print(filename)
Mineure « Data Science » Frédéric Pennerath
L’écriture formatée de fichiers et
les chaînes de formatage
Simple substitution :
>> S = "{} : capitale = {2}, surface = {1} m2"
>> S.format(’France’,674843, ’Paris’)
→ ’France : capitale = Paris, surface = 674843 m2’
Justification au centre à gauche et à droite:
>> S = "{:^10} : capitale = {:.<10}, surface = {:>10} m2"
>> S.format(’France’, ’Paris’, 674843)
→ ' France : capitale = Paris....., surface = 674843 m2'
Formattage des nombres
>> "{:.2f}".format(3.1415) → '3.14'
>> "{:.2e}".format(3.1415) → '3.14e+00'
>> "{:.1%}".format(0.1531) → '15.3%'
Mineure « Data Science » Frédéric Pennerath
L’analyse de fichiers et
les expressions régulières
Expression régulière :
Décrit un ensemble des chaînes de caractères reconnues par un automate
Langage des expressions régulières :
langage de spécification d’un automate
Exemple : \d+ succession de chiffres de 0 à 9
Utile pour analyser le contenu de fichiers textes
Compilation génération de l’automate
>> import re
>> S = "T = -40, P = 100, V = 2.1"
>> expr = re.compile(’\d+’)
>> expr.findall(S)
→ ['40', '100', '2', '1']
>> expr = re.compile('-?\d+\.?\d+') ; expr.findall(S)
→ ['-40', '100', '2.1']
>> expr.split(S)
→ ['T = ', ', P = ', ', V = ', '']
>> expr = re.compile('(\w+)\s*=\s*(-?\d+\.?\d+)') ; expr.findall(S)
→ [('T', '-40'), ('P', '100'), ('V', '2.1')]
Mineure « Data Science » Frédéric Pennerath
Les expressions régulières
Expression Correspondance
. Tout caractère
[x-y] Tout caractère entre x et y inclus
\w, \d, \s Tout caractère alphanumérique, tout chiffre, tout espace
\W, \D, \S Négations de \w, \d, \s
exp* Occurrences de exp de 0 ou plusieurs fois
exp+ Occurrences de exp au moins une fois
exp? Occurrences de exp au plus 1 fois
exp{n,m} Occurrences de exp de n à m fois
(exp) Fait correspondre exp à une variable $n
exp1|exp2 Alternative entre exp1 et exp2
^,$ Correspond au début et à la fin de la chaîne
\x Caractère x, si x est un caractère spécial (.,*,\,+,?,|,…)
Mineure « Data Science » Frédéric Pennerath
Exercices
Exercice 1 : tests et boucles
Afficher la liste des nombres premiers compris 1 et n en testant s’il existe pour
chaque entier un diviseur.
Exercice 2 : listes
Même exercice avec le crible d’Eratosthène
Exercice 3 : dictionnaires et fichiers
Lire un fichier texte en entrée et écrire dans un fichier en sortie :
• Soit la liste des mots associés à leur fréquence
• Soit la liste des numéros des lignes où apparaissent un mot donné
Les paramètres seront passés en argument de la ligne de commande.
Mineure « Data Science » Frédéric Pennerath
La programmation objet
class Poly:
'un polynome a coefs reels'
# Constructeur
def __init__(self, C=[]):
self.coefs = C
# Conversion str(self)
def __str__(self):
L = [ "{:2.2f} X^{}".format(self.coefs[i],i)
for i in range(len(self.coefs)) ]
L.reverse()
return "+".join(L)
# Opération self + P
def __add__(self, P):
L = [ (x + y) for (x,y) in zip(self.coefs, P.coefs) ]
L += self.coefs[len(P.coefs):]
L += P.coefs[len(self.coefs):]
return Poly(L)
# Attributs statiques
Poly.X = Poly([0, 1]) # Monôme X
Poly.I = Poly([1]) # Constante 1from Poly import Poly
P = Poly([0, 1])
print(P + Poly.X)
Fichier « Poly.py »
Mineure « Data Science » Frédéric Pennerath
Les itérateurs
Itérateur : permet l’énumération d’éléments (pas forcément de structures de
données sous-jacentes)
Exemple : range(min, max, step)
>> L = list(range(1,10000))
>> sys.getsizeof(L) → 80056
>> G = range(1,10000)
>> sys.getsizeof(G) → 32 !!!
Itérateurs paresseux versus liste par compréhension
>> L2 = [ 2*x for x in G ]
>> sys.getsizeof(L2) → 87624
>> G2 = ( 2*x for x in G )
>> sys.getsizeof(G2) → 72 !!!
Exemple d’application : transformation d’un fichier en Θ(1)
>> f = open(fileName, 'r')
>> g = ( l.upper() for l in f )
>> for l in g: print(l)
Mineure « Data Science » Frédéric Pennerath
Itérateurs et itérables « faits maison »
class Poly:
...
# Itérable : retourne un itérateur
def __iter__(self): return Iter(self.coefs)
class Iter:
# Constructeur de l'itérateur
def __init__(self, coefs):
self.it = iter(coefs) # Itérateur de la liste de coefs.
self.degre = -1
# next renvoie le prochain élément ou exception StopIteration
def __next__(self):
while(True):
coef = next(self.it) # Peut produite une StopIteration
self.degre += 1
if(coef != 0.): return(coef, self.degre)
# Un itérateur est un itérable
def __iter__(self): return self