python - metz.supelec.fr · mineure « data science » frédéric pennerath plan de travail •...

29
Mineure « Data Science » Frédéric Pennerath PYTHON OU LE COUTEAU SUISSE DU DATA SCIENTIST Chapitre 2

Upload: trannga

Post on 11-Sep-2018

231 views

Category:

Documents


4 download

TRANSCRIPT

Mineure « Data Science » Frédéric Pennerath

PYTHONOU LE COUTEAU SUISSE DU DATA SCIENTIST

Chapitre 2

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

PROGRAMMATION

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

Mineure « Data Science » Frédéric Pennerath

Les générateurs

class Poly:

...

# Renvoie un générateur

def getCoefs(self):

degre = 0

for c in self.coefs:

if(c != 0.):

# yield renvoie une valeur

yield (degre, c)

degre += 1

for c in P.getCoefs():

print(c)