Résumé Présentation de pyhton, exécution de commandes interactives ou de scripts avec un IDE, utilisation d'un calepin; les types et structures élémentaires de données, les structures de contrôle, les fonctions, classes et modules. Introduction à l'utilisation des librairies scientifiques: Numpy, Matplotlib, Scipy
et au type array
.
Ce calepin introduit le langage libre Python et décrit les premières commandes nécessaires au pré-traitement des données avant l'utilisation de méthodes statistiques avec ce langage ou avec R. Les aspects statistiques développés dans les différentes vignettes de Wikistat sont supposés acquis ainsi qu'une connaissance des principes élémentaires de programmation dans un langage matriciel comme R ou Matlab.
Pour des approfondissements, il existe de très nombreuses ressources pédagogiques accessibles sur la toile dont le tutoriel officiel de Python 3.4., les sites pythontutor.com
, courspython.com
, le livre de Sheppard (2014) qui présentent une introduction à Python pour l'\'Econométrie et la Statistique et celui de Mac Kinney (2013), principal auteur de la bibliothèque pandas
.
Python et ses librairies peuvent être installés dans quasiment tout environnement matériel et système d'exploitation à partir du site officiel. Voici les principales librairies scientifiques définissant des structures de données et fonctions de calcul indispensables.
ipython
: pour une utilisation interactive de Python, numpy
: pour utiliser vecteurs et tableaux, scipy
: intègre les principaux algorithmes numériques, matplotlib
: pour les graphes, pandas
: structure de données et feuilles de calcul, patsy
: formules statistiques,statsmodels
: modélisation statistique,seaborn
: visualisation de données,scikit-learn
: algorithmes d'apprentissage statistique.Néanmoins, compte tenu de la complexité de l'opération, il est plus simple pour le néophyte, surtout sous Windows, de faire appel à une procédure d'installation intégrant les principales librairies. Ces procédures sont développées par des entreprises commerciales mais libres de droits pour une utilisation académique.
Conda
est l'utilitaire (commande en ligne) qui permet les mises à jour et installations des librairies complémentaires.D'un point de vue légal, les propositions sont identiques mais Canopy nécessite la création d'un compte académique. Seul "souci", ces versions n'incluent que les versions dites stables des différentes librairies et donc avec un temps de retard vis-à-vis des versions encore développement.
C'est Anaconda qui est utilisée ici, car préférable pour un poste personnel, en version 2.7; C'est aussi la version installée par le CSN de l'INSA dans les salles de TP.
Python exécute programmes ou scripts, programmes qui peuvent être pré-compilés pour plus d'efficacité. Ce langage s'exécute également à l'aide d'un interprète de commande (IDLE
) ou {IPython
) de manière interactive. En situation pédagogique, c'est l'utilisation et la réalisation d'un notebook Ipython (calepin) ou plutôt maintenant Jupyter qui est privilégiée à partir d'un simple navigateur (éviter internet explorer).
Les commandes sont regroupées dans des cellules suivies de leur résultat après exécution. Ces résultats et commentaires sont stockés dans un fichier spécifique .ipynb
et sauvegardés. Les commandes LaTeX sont acceptées pour intégrer des formules, la mise en page est assurée par des balises HTML ou Markdown.
La commande de sauvegarde permet également d'extraire les seules commandes Python dans un fichier d'extension .py
. C'est une façon simple et efficace de conserver tout l'historique d'une analyse pour en faire une présentation ou créer un tutoriel. Le calepin peut être en effet chargé sous un autre format: page html
, fichier .pdf
ou diaporama.
Le projet Jupyter propose cet environnement de calepin pour beaucoup de langages (Pyhton, Julia, Scala...) dont R. Il devient un outil indispensable pour assurer simplement la reproductibilité des analyses.
L'ouverture d'un navigateur sur un calepin (Ipython ou Jupyter) est obtenu, selon l'installation, à partir des menus ou en exécutant:
jupyter notebook
ou
ipython notebook
dans une fenêtre de commande.
Une fois le calepin ouvert,
.ipynb
.html
pour une page web..py
regroupant les commandes python pour une version opérationnelle.Attention Un calepin de IPython ou Jupyter est un outil de travail exploratoire efficace et un compte rendu nécessairement chronologique d'exécution; ce n'est pas le rapport d'une étude statistique dont l'organisation suit des règles spécifiques.
Spyder
Pour la réalisation d'applications et programmes plus complexes, l'usage d'un IDE (integrated Development Environment) libre comme Spyder est recommandé. Ce dernier est intégré à la distribution Anaconda
et sa présentation proche de celles de Matlab ou RStudio. Cet environnement exécutant IPython reconnaît évidemment les commandes précédentes.
Comme pour RStudio, Spider
ouvre plusieurs fenêtres:
#%%
.En résumé, utiliser un calepin pour des analyses exploratoires élémentaires et un IDE Spyder
ou Eclipse
(un peu compliqué!) pour la construction de programmes et modules.
Selon l'installation et à partir du répertoire de travail, exécuter la commande:
jupyter notebook
qui ouvre le navigateur par défaut.
Sur les postes géré par le CSN de l'INSA, si cela ne marche pas, il peut être nécessaire d'ajouter une variable d'environnement:
export PATH=/usr/local/insa/anaconda/bin:$PATH
Entrer les commandes ci-dessous dans le calepin et les exécuter cellule par cellule en cliquant sur le bouton d'exécution de la cellule courante.
In [ ]:
# Ceci est le début d'une session Python gérée à l'aide d'un calepin.
# Le script est divisé en cellules avec généralement l'affichage d'au plus un résultat par cellule.
## Importer les librairies nécessaires
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from pylab import *
import os
## Définir si nécessaire le répertoire courant spécifique
## à l'utilisateur
os.chdir(r'.')
## Commande magique pour obtenir les graphiques dans le calepin
%matplotlib inline
In [ ]:
#%% Créer un data frame avec pandas
data = pd.DataFrame({
'Gender': ['f', 'f', 'm', 'f', 'm', 'm', 'f', 'm', 'f', 'm'],
'TV': [3.4, 3.5, 2.6, 4.7, 4.1, 4.0, 5.1, 4.0, 3.7, 2.1]})
data
In [ ]:
# Génération de variables aléatoires gaussiennes
xx = randn(100,100)
y = mean(xx,0)
# graphique
plot(y)
show()
In [ ]:
a=3 # est un entier
b=1. # est un flottant
# Attention:
a/2 # a pour résultat 1.5 en Python 3.4
# mais 1 en 2.7
Opérateurs de comparaison : ==, >, <, !=
de résultat booléen.
In [ ]:
# Comparaison
a==b
In [ ]:
# affichage et type des variables
type(a)
In [ ]:
# Chaîne de caractère
a='bonjour '
b='le '
c='monde'
a+b+c
Attention à l'encodage des caractères. Ce n'est pas le même en python 2 (ascii) et python 3 (utf-8). Ce n'est pas fait dans ces exemples élémentaires mais il est vivement recommander de gérer systématiquement des textes complexes avec caractères spéciaux (accents, guillements...) en utf-8
In [ ]:
a=u'bonjour' # encodage utf-8
type(a)
In [ ]:
a='bonjour' # encodage ascii
type(a)
In [ ]:
# exemples de listes
liste_A = [0,3,2,'hi']
liste_B = [0,3,2,4,5,6,1]
liste_C = [0,3,2,'hi',[1,2,3]]
# Elément d'une liste
liste_A[1]
In [ ]:
liste_C[-1] # dernier élément
In [ ]:
liste_C[-1][0]
In [ ]:
liste_C[-2]
In [ ]:
liste_B[0:2] # Sous-liste
In [ ]:
liste_B[0:5:2] # début:fin:pas
In [ ]:
liste_B[::-1]
In [ ]:
# Fonctions de listes
List=[3,2,4,1]
List.sort()
print(List)
In [ ]:
List.append('hi')
print(List)
In [ ]:
List.count(3)
In [ ]:
List.extend([7,8,9])
print(List)
In [ ]:
List.append([10,11,12])
print(List)
In [ ]:
MyTuple=(0,3,2,'h')
MyTuple[1]
In [ ]:
MyTuple[1]=10 # TypeError: "tuple" object
In [ ]:
months = {'Jan':31 , 'Fev': 28, 'Mar':31}
months['Jan']
In [ ]:
months.keys()
In [ ]:
months.values()
In [ ]:
months.items()
Un bloc de commandes ou de codes est défini par deux points suivis d'une indentation fixe. Cela oblige à l'écriture de codes faciles à lire mais à être très attentif sur la gestion des indentations car la fin d'indentation signifie la fin d'un bloc de commandes.
In [ ]:
# si alors sinon
a=2
if a>0:
b=0
print(b)
else:
b=-1
print(b)
In [ ]:
for i in range(4):
print(i)
In [ ]:
for i in range(1,8,2):
print(i)
In [ ]:
# Définition d'une fonction
def pythagorus(x,y):
""" Calcule l'hypotenuse d'un triangle """
r = pow(x**2+y**2,0.5)
return x,y,r
pythagorus(3,4)
In [ ]:
# exemple d'appel
pythagorus(x=3,y=4)
In [ ]:
# aide intégrée
help(pythagorus)
In [ ]:
pythagorus.__doc__
In [ ]:
# Valeurs des paramètres par défaut
def pythagorus(x=1,y=1):
""" calcule l'hypoténuse d'un triangle """
r = pow(x**2+y**2,0.5)
return x,y,r
pythagorus()
Un module contient plusieurs fonctions et commandes qui sont regroupées dans un fichier d'extension .py
. Insérer un fichier vide de nom _init_.py
dans chaque dossier et sous-dossier contenant un module à importer. Un module est appelé par la commande import
. Un module est considéré comme un script s'il contient des commandes. Lors de l'import d'un script, les commandes sont exécutées tandis que les fonctions sont seulement chargées.
Commencer par définir un module dans un fichier texte contenant les commandes suivantes.
def DitBonjour():
print("Bonjour")
def DivBy2(x):
return x/2
Sauver le fichier avec pour nom testM.py
dans le répertoire courant.
Il est possible d'importer toutes les fonctions en une seule commande import
.
In [ ]:
import testM
testM.DitBonjour()
In [ ]:
print(testM.DivBy2(10))
In [ ]:
from testM import *
DitBonjour()
In [ ]:
print(DivBy2(10))
Ou seulement celles qui seront utilisées. Préférer cette dernière méthode pour les grosses librairies.
In [ ]:
import testM as tm
tm.DitBonjour()
In [ ]:
print(tm.DivBy2(10))
# délétion des objets
%reset
In [ ]:
from testM import DitBonjour
DitBonjour()
In [ ]:
print(DivBy2(10)) # erreur
Lors de son premier appel, un module est pré-compilé dans un fichier .pyc
qui est utilisé pour les appels suivants. Attention, si le fichier a été modifié / corrigé, il a besoin d'être rechargé par la commande reload(name)
.
Une librairie (package) regroupe plusieurs modules dans différents sous-répertoires. Le chargement spécifique d'un des modules se fait en précisant le chemin.
import sound.effects.echo
NumPy
Cette librairie définit le type de données array
ainsi que les fonctions de calcul qui y sont associées. Il contient aussi quelques fonctions d'algèbre linéaire et statistiques.
Il n'est finalement utilisé que pour la définition du type array
car les fonctions numériques sont beaucoup plus développées dans SciPy
.
Matplotlib
Celle-ci propose des fonctions de visualisation / graphs avec des commandes proches de celles de Matlab. Aussi connue sous le nom de pylab
. La gallerie de cette librairie propose tout un ensemble d'exemples de graphiques avec le code Python pour les générer.
In [ ]:
# Importation
import numpy as np
from pylab import *
gaussian = lambda x: np.exp(-(0.5-x)**2/1.5)
x=np.arange(-2,2.5,0.01)
y=gaussian(x)
plot(x,y)
xlabel("x values")
ylabel("y values")
title("Gaussian function")
show()
SciPy
Cette librairie est un ensemble très complet de modules d'algèbre linéaire, statistiques et autres algorithmes numériques. Le site de la documentation en fournit la liste.
C'est de loin la structure de données la plus utilisée pour le calcul scientifique sous Python. Elle décrit des tableaux ou matrices multi-indices de dimension $ n = 1, 2, 3, \ldots , 40$. Tous les éléments sont de même type (booléen, entier, réel, complexe).
Il est possible de contrôler précisément le type d'un array
, par exemple pour gagner de la place en mémoire, en codant les entiers sur 8, 16, 32 ou 64 bits, de même pour les réels (float) ou les complexes.
Les tableaux ou tables de données (data frame), bases d'analyses statistiques et regroupant des objets de types différents sont décrits avec la librairie pandas
.
array
In [ ]:
# Importation
import numpy as np
my_1D_array = np.array([4,3,2])
print(my_1D_array)
In [ ]:
my_2D_array = np.array([[1,0,0],[0,2,0],[0,0,3]])
print(my_2D_array)
In [ ]:
myList=[1,2,3]
my_array = np.array(myList)
print(my_array)
In [ ]:
a=np.array([[0,1],[2,3],[4,5]])
a[2,1]
In [ ]:
a[:,1]
In [ ]:
np.arange(5)
In [ ]:
np.ones(3)
In [ ]:
np.ones((3,4))
In [ ]:
np.eye(3)
In [ ]:
np.linspace(3, 7, 3)
In [ ]:
np.mgrid[0:3,0:2]
In [ ]:
D=np.diag([1,2,4,3])
print(D)
print(np.diag(D))
In [ ]:
M=np.array([[10*n+m for n in range(3)]
for m in range(2)])
print(M)
Le module numpy.random
fournit toute une liste de fonctions pour la génération de matrices aléatoires.
In [ ]:
from numpy import random
random.rand(4,2) #tirage uniforme
In [ ]:
random.randn(4,2) #tirage selon la loi N(0,1)
In [ ]:
v=random.randn(1000)
import matplotlib.pyplot as plt
h=plt.hist(v,20) # histogramme à 20 pas
show()
In [ ]:
A=random.randn(64,64)
plt.imshow(A,interpolation="nearest")
plt.colorbar
plt.show()
In [ ]:
# Sauver, écrire dans un fichier, lire un fichier
M=random.randn(10,10)
np.savetxt('data.csv',M,fmt='%2.2f',delimiter=',')
#au format propre à numpy : npy
In [ ]:
np.save('data.npy',M)
np.load('data.npy')
In [ ]:
v=np.array([1,2,3,4,5])
print(v)
In [ ]:
v[1:4]
In [ ]:
v[1:4:2]
In [ ]:
v[::]
In [ ]:
v[ : :2] # par pas de 2
In [ ]:
v[ : 3]
In [ ]:
v[3 :] # à partir de l'indice 3
In [ ]:
v[-1] # dernier élément
In [ ]:
v[-2 :] # deux derniers éléments
In [ ]:
M=random.rand(4,3)
print(M)
In [ ]:
ind=[1,2]
M[ind] # lignes d'indices 1 et 2
In [ ]:
M[:,ind] # colonnes d'indices 1 et 2
In [ ]:
M[[0,2],[1,2]] # renvoie M[0,1] et M[2,2]
In [ ]:
M[np.ix_([0,2],[1,2])]
In [ ]:
(M>0.5)
In [ ]:
M[M>0.5]
In [ ]:
a=np.array([[0,1],[2,3],[4,5]])
np.ndim(a) # Nombre de dimensions)
In [ ]:
np.size(a) # Nombre d’éléments
In [ ]:
np.shape(a) # Tuple contenant la dimension de a
In [ ]:
np.transpose(a) # Transposée
In [ ]:
a.T # autre façon de définir la transposée
In [ ]:
a.min(), np.min(a) # Valeur min
In [ ]:
a.sum(), np.sum(a) # Somme des valeurs
In [ ]:
a.sum(axis=0) # Somme sur les colonnes
In [ ]:
a.sum(axis=1) # sur les lignes
Quelques manipulations:
In [ ]:
np.r_[1:4,10,11] # Concaténation en ligne
In [ ]:
np.c_[1:4,11:14] # Concaténation en colonne
In [ ]:
np.c_[1:4,11:15] # erreur
In [ ]:
np.arange(6).reshape(3,2)
In [ ]:
A=np.array([[1,2],[3,4]])
np.tile(A,(3,2)) # Répétition de la matrice A
In [ ]:
A=np.array([[1,2],[3,4]])
B=np.array([[11,12],[13,14]])
#Concaténation en ligne
np.concatenate((A,B),axis=0)
In [ ]:
# Equivalent à
np.vstack((A,B))
In [ ]:
# Concaténation en colonne
np.concatenate((A,B),axis=1)
In [ ]:
# Equivalent à
np.hstack((A,B))
In [ ]:
# somme
a=np.arange(6).reshape(3,2)
b=np.arange(3,9).reshape(3,2)
c=np.transpose(b)
a+b
In [ ]:
a*b # produit terme à terme
In [ ]:
np.dot(a,c) # produit matriciel
In [ ]:
np.power(a,2)
In [ ]:
np.power(2,a)
In [ ]:
a/3
Les fonctions genfromtxt
, avetxt
permettent de lire, écrire des fichiers textes par exemple au format .csv
mais ces fonctionnalités sont plus largement abordées avec la librairie pandas
.
In [ ]:
# Importation
import numpy as np
from scipy import linalg
A = np.array([[1,2],[3,4]])
linalg.inv(A)
In [ ]:
linalg.det(A)
In [ ]:
la,v = linalg.eig(A)
l1,l2 = la
# valeurs propres
print(l1, l2)
In [ ]:
# 1er vecteur propre
print(v[:,0])
In [ ]:
# SVD de A
U,s,V = linalg.svd(A)
print(s**2)
In [ ]:
linalg.eig(np.dot(np.transpose(A),A))
In [ ]:
# Importation
import scipy.stats
rvs1 = scipy.stats.norm.rvs(loc=5, scale=10,size=500)
rvs2 = scipy.stats.norm.rvs(loc=5, scale=10,size=500)
rvs3 = scipy.stats.norm.rvs(loc=8, scale=10,size=500)
# t-test returns: t-statistic/two-tailed p-value
scipy.stats.ttest_ind(rvs1, rvs2)
In [ ]:
scipy.stats.ttest_ind(rvs1, rvs3)
In [ ]:
# Kolmogorov-Smirnov test
# returns: KS statistic / two-tailed p-value
scipy.stats.ks_2samp(rvs1, rvs2)
In [ ]:
scipy.stats.ks_2samp(rvs1, rvs3)