Rappel - Legos

Transcription

Rappel - Legos
Formation Python
Traitement et visualisation de données
scientifiques
Jour 3 – Optimisation et calcul
Fernando NIÑO
Legos/IRD
Janvier 22-30
2009
Python Scientifique
Formation Python
Python - Divers
Rappels
Dates
Fichiers Tar
Persistence
Optimisation
Matplotlib/Mayavi
© 2009 Fernando NIÑO
2
Python Scientifique
Formation Python
Python - Divers
Syntaxe
Rappels
Classes
Exceptions
Dates
Fichiers Tar
Persistence
Optimisation
Matplotlib/Mayavi
© 2009 Fernando NIÑO
3
Rappel
• Littéraux
– Comme toujours, mais avec “”” .... “”” et r”\non interp”
• Structures de données
– Séquences (listes)
– Dictionnaires
– Tuples
• Blocs : indentation et symbole ‘:’
for i in liste:
suite
while i < 3:
• Python = réutilisation
– Bibliothèque standard
– Modules externes
python setup.py install --home=~
© 2009 Fernando NIÑO
4
Rappel (2)
• Fonctions
– Définies avec le mot clé def
• Classes
Classe Mère
– Bon nommage (commence par majuscule, sans tiret)
– Structure
import xxxxx
class MaClasse(object):
<<variables de classe>>
def __init__(self,args):
self.varinstance1 = None
<<autres choses>>
<<autres defs>>
– fonctions de classes: premier argument toujours “self”
– variable __nnnnn indique que la variable est privée.
© 2009 Fernando NIÑO
5
Rappel (3)
• Exceptions
– On soulève une exception avec raise
raise KeyboardInterrupt
– On les attrape avec try/except
try:
x=1
y=2
...
except SousclasseException, variableException:
print “J’ai attrape” + str(variableException)
– La clause finally marche comme ça:
try:
x=1
finally:
print “j’ai fait toujours cela”
© 2009 Fernando NIÑO
6
Rappel (4): numpy
• numpy est la version moderne de Numerix et
Numeric; elle les remplace.
• scipy est une extension basée sur numpy
• matplotlib est une bibliothèque censé
remplacer les graphiques de Matlab.
• numpy définit:
– array et beaucoup d’opérations
– définition de types
– conversion de données binaires à l’aide de types (recarray)
© 2009 Fernando NIÑO
7
Python Scientifique
Formation Python
Python - Divers
Rappels
Dates
DateTime
mxDateTime
Fichiers Tar
Persistence
Optimisation
Matplotlib/Mayavi
© 2009 Fernando NIÑO
8
Manipulation de dates
• Module standard: datetime
–
–
–
–
–
datetime.date : toujours et uniquement cal. Gregorien
datetime.time: toujours 24*60°60 secondes par jour
datetime.datetime.now() : renvoie l’heure et date courantes
...
..
• Module non-standard: mx.DateTime
– Très utilisé et stable: v3.1; nécessaire pour certains SQL
– Plus complet, gère en particulier JulianDateTime
– Arithmétique plus simple:
from mx.DateTime import now, RelativeDateTime
# Le premier jour du mois prochain, même heure
now()+RelativeDateTime(months=+1,day=1)
© 2009 Fernando NIÑO
9
mx.DateTime installation
• Deux possibilités:
easy_install egenix-mx-base
– ou
python setup.py install --home=/home/user
© 2009 Fernando NIÑO
10
Temps vécu: mx.DateTime
from mx.DateTime import *
import string,sys
print 'Please enter your birthday (year,month,day), e.g.
1969,12,1:'
try:
year,month,day = input('>>> ')
except:
print '* Sorry, wrong entry.'
sys.exit()
birthday = Date(year,month,day)
lifespan = now() - birthday
print 'Lifespan:'
print ' =',lifespan.days,'days'
print ' =',int(lifespan / (29.53 * oneDay)),'moons (+/- 1)'
print ' =',lifespan / (365.2422 * oneDay),'tropical years'
© 2009 Fernando NIÑO
11
Temps vécu: datetime
from datetime import *
import string,sys
print 'Please enter your birthday (year,month,day), e.g.
1969,12,1:'
try:
year,month,day = input('>>> ')
except:
print '* Sorry, wrong entry.'
sys.exit()
birthday = date(year,month,day)
lifespan = date.today() - birthday
print 'Lifespan:'
print ' =',lifespan.days,'days'
Erreur !
oneDay = 24*60*60
print ' =',int(lifespan / (29.53 * oneDay)),'moons (+/- 1)'
print ' =',lifespan / (365.2422 * oneDay),'tropical years'
© 2009 Fernando NIÑO
12
Python Scientifique
Formation Python
Python - Divers
Rappels
Dates
Fichiers Tar
Persistence
Optimisation
Matplotlib/Mayavi
© 2009 Fernando NIÑO
13
Fichiers tar
• Ecriture
import tarfile
tar= tarfile.open('toto.tgz','w:gz')
for file in ['hdf5_1.py','hdf5_2.py']:
tar.add(file)
tar.close()
• Lecture
import time
tar= tarfile.open('toto.tgz','r:gz')
for file in tar.getmembers():
print "%s: size=%d mtime=%s" % (file.name,
file.size, time.strftime('%Y/%m/%d',time.gmtime
(file.mtime)))
14
tar.close()
© 2009 Fernando NIÑO
Python Scientifique
Formation Python
Python - Divers
Rappels
Dates
Fichiers Tar
Pickling
Persistence
PostgreSQL
numpy.save, save, fromfile
Optimisation
Matplotlib/Mayavi
© 2009 Fernando NIÑO
15
Persistance
• Persistance: stocker quelque part le contenu de
la mémoire, pour y revenir plus tard.
– Stockage binaire brut:
pickling
shelving
cPickling
struct
--> Le plus simple et efficace
– Stockage sous forme texte
__str__ ou __repr__
© 2009 Fernando NIÑO
16
cPickling
• Basé sur une implementation en C
• cpick.py
– Ecriture
import cPickle
import numpy
a='Ma chaine A'
b=numpy.array([34,56])
c=0.101
f=open('totopick','w')
cPickle.dump(a,f)
cPickle.dump(b,f)
cPickle.dump(c,f)
f.close()
© 2009 Fernando NIÑO
17
cPickling
• cpick.py
– Lecture: l’ordre doit être respecté.
f=open('totopick','r')
a=cPickle.load(f)
b=cPickle.load(f)
c=cPickle.load(f)
f.close()
print
print
print
print
'Valeurs relues:'
a
b
c
© 2009 Fernando NIÑO
18
PostgreSQL
• En dehors du cadre de la discussion !
• MAIS, on peut recommande l’utilisation du pilote
psycopg/psycopg2
import psycopg2
try:
conn = psycopg2.connect("dbname='template1'
user='dbuser' host='localhost'
password='dbpass'");
except:
print "I am unable to connect to the database
cur=conn.cursor()
cur.execute("""SELECT datname from pg_database""")
© 2009 Fernando NIÑO
19
numpy save, tofile, fromfile
– save/load (saveload.py)
import numpy as np
a=np.arange(10)
a=a**2
np.save('myfile', a)
a=None
a = np.load('myfile.npy')
– tofile (tofileex.py)
from numpy import *
x = arange(10.)
y = x**2
y.tofile("myfile.dat") # binaire
y.tofile("myfile1.txt", sep=' ', format = "%e")
# ascii format, one row, exp notation, values
separated by 1 space
y.tofile("myfile2.txt", sep='\n', format = "%e") 20
© 2009 Fernando NIÑOnotation
# ascii format, one column, exponential
numpy save, tofile, fromfile
– fromfile (fromfileex.py)
y0=fromfile('myfile.dat', dtype=float)
y1=fromfile('myfile1.txt', dtype=float, sep=' ')
y2=fromfile('myfile2.txt', dtype=float, sep='\n')
assert(all(y0=y))
assert(all((y1==y) == True))
assert(all(y2==y))
• Parenthèse: all/any (à partir de Python 2.5)
def all(x):
return reduce(lambda a,b:a and b, x)
def any(x):
return reduce(lambda a,b:a or b, x)
© 2009 Fernando NIÑO
21
Python Scientifique
Formation Python
Python - Divers
Rappels
Dates
Fichiers Tar
Persistence
Profiling
Optimisation
Interface avec C/C++
Multiprocessing
Matplotlib/Mayavi
© 2009 Fernando NIÑO
22
Fils d'exécution
• TRES important à cause de l’évolution de
l’architecture informatique
– A cause des problèmes de dissipation de la chaleur, la
puissance est augmentée non plus par augmentation de la
fréquence du processeur, mais par l’intégration de
plusieurs coeurs de calcul au sein d’un même processor
– CPU 1 coeur 400 MHz --> CPU 1 coeur 2.8 Ghz
– CPU 1 coeur 3GHz --> CPU bicoeur 2GHz
• Les calculs vont plus vite seulement si l’on peut
exploiter plusieurs fils d’exécution.
© 2009 Fernando NIÑO
23
GIL
• Le Global Interpreter Lock est un verrou au
niveau du coeur de Python qui l’empêche de faire
tourner plus d’un fil d’éxécution à la fois.
• Solution : utiliser des processus et non pas de
threads pour les calculs... c’est plus lourd, mais
ça marche.
• A partir de la version 2.6 de Python, le module
multiprocessing permet de faire exactement
cela.
© 2009 Fernando NIÑO
24
Solution bis:
• Pour du calcul
– Utiliser Python dans son domaine
– Utiliser une librairie parallèle pour le calcul vraiment
intensif...(e.g. OpenMP)
• Pour les tâches non-calcul
– threads si c’est pas trop pénalisant
– multiprocessing si l’on utiliser Python > 2.6
• Mais comment savoir si c’est pénalisant ?
– Profiling
• Si machine 32 bits, Psyco marche très bien de
façon transparente. En 64 bits, ça ralentit...
© 2009 Fernando NIÑO
25
Profiling
• Le principe de 20-80 : 20% du code utilise 80%
du temps processeur...
• Toujours: mesurer avant d’optimiser.
• Quoi qu’il résulte, toujours privilégier la facilité
de maintenance et la lisibilité du code; si besoin,
utiliser le paradigme de Bill:
– si c’est trop lent, attendez que le hardware soit plus
rapide...
© 2009 Fernando NIÑO
26
Profiling avec time, timeit
• Première approche: utiliser le temps réel
– profil1.py
import time
e0 = time.time() # elapsed time since the epoch
c0 = time.clock() # total CPU time spent in the
script so far
#<do tasks...>
elapsed_time = time.time() - e0
cpu_time = time.clock() - c0
• Deuxième approche, module timeit
– profil2.py
import timeit
t = timeit.Timer(’sin(1.2)’,
setup=’from math import sin’)
t.timeit(1000) # Lancer 1000 fois
© 2009 Fernando NIÑO
27
Profiling
• Auparavant il y avait des modules hotshot, et
profile...
• Aujourd’hui, un seul est recommandé: cProfile
– Utilisation basique
import cProfile
cProfile.run('foo()') # foo() routine à analyser
– Stockant les statistiques (profil3.py)
import cProfile
cProfile.run('foo()',’foo.stats’)
© 2009 Fernando NIÑO
28
Profiling: statistiques (1/2)
In [101]: pstats.Stats.sort_arg_dict_default
Out[101]:
{'calls': (((1, -1),), 'call count'),
'cumulative': (((3, -1),), 'cumulative time'),
'file': (((4, 1),), 'file name'),
'line': (((5, 1),), 'line number'),
'module': (((4, 1),), 'file name'),
'name': (((6, 1),), 'function name'),
'nfl': (((6, 1), (4, 1), (5, 1)), 'name/file/
line'),
'pcalls': (((0, -1),), 'call count'),
'stdname': (((7, 1),), 'standard name'),
'time': (((2, -1),), 'internal time')}
© 2009 Fernando NIÑO
29
Profiling: statistiques (2/2)
• Voir profil4.py
# Read all 5 stats files into a single object
stats = pstats.Stats('profile_stats_0.stats')
for i in range(1, 5):
stats.add('profile_stats_%d.stats' % i)
# Clean up filenames for the report
stats.strip_dirs()
# Sort the statistics by the cumulative time spent
in the function
stats.sort_stats('cumulative')
© 2009 Fernando NIÑO
30
Subprocess
• Module standard subprocess
import subprocess
try:
subprocess.check_call(["ls","-l",'/dfdf'])
except OSError, err:
print "commande ne pouvant pas être executée"
except ValueError, err:
print "Invalid arguments"
except subprocess.CalledProcessError, err:
print"retour n'est pas 0..%s" % str(err)
except Exception, err :
print "Autre chose..%s" % str(err)
else:
print "Bravo tout ok"
© 2009 Fernando NIÑO
31
Extensions de Python
• Utilitaire swig (http://www.swig.org)
– Génération de l’enveloppe
swig -python swig_example.i
– Compilation et génération de librairie dynamique
gcc -fpic -c swig_example.c swig_example_wrap.c \
-I/usr/local/include/python2.4
ld -shared swig_exemple.o swig_exemple_wrap.o -o
swig_exemple.so
• Utilisation:
>>> import swig_example
>>> swig_example.fact(5)
120
>>> swig_example.my_mod(7,3)
1
>>> swig_example.get_time()
'Sun Feb 11 23:01:07 1996'
© 2009 Fernando NIÑO
32
SWIG: module c
/* File : example.c */
#include <time.h>
double My_variable = 3.0;
int fact(int n) {
if (n <= 1) return 1;
else return n*fact(n-1);
}
int my_mod(int x, int y) {
return (x%y);
}
char *get_time()
{
time_t ltime;
time(&ltime);
return ctime(&ltime);
}
© 2009 Fernando NIÑO
33
SWIG: interface
/* example.i */
%module swig_exemple
%{
/* Put header files here or function declarations
like below */
extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();
%}
extern
extern
extern
extern
double My_variable;
int fact(int n);
int my_mod(int x, int y);
char *get_time();
© 2009 Fernando NIÑO
34
SWIG: librairies dynamiques
• Linux
– Pour C:
$ cc -fpic -c $(SRCS)
$ ld -shared $(OBJS) -o module.so
– Pour C++:
$ c++ -fpic -c $(SRCS)
$ c++ -shared $(OBJS) -o module.so
• MacOSX:
ld -bundle -flat_namespace -undefined suppress -o
_example2.so example2.o example2_wrap.o
© 2009 Fernando NIÑO
35
SWIG et numpy
• Plus compliqué !
– Dossier examples2/python_numpy_swig
. makefile
-rwxrwxr-x 1 nino
_example2.so*
Initialisation ok
a = np.zeros ok
[0] = 0.000000
[1] = 0.000000
[2] = 0.000000
[3] = 0.000000
fin - tout ok
nino
41204
5 fév 02:55
© 2009 Fernando NIÑO
36
Multiprocessing
• Beaucoup d’approches
– Distribués: CORBA/DCOM PyRO
– Cluster computing: Linda, NetWorkSpaces...
– Grilles: pyGrid
http://wiki.python.org/moin/ParallelProcessing
•
© 2009 Fernando NIÑO
37
Multiprocessing
• A partir de 2.6 ...
from multiprocessing import Pool
def f(x):
return x*x
if __name__ == '__main__':
pool = Pool(processes=4)
result = pool.apply_async(f, (10,))
asynchronously
print result.get(timeout=1)
computer is *very* slow
print pool.map(f, range(10))
it = pool.imap(f, range(10))
print it.next()
print it.next()
print it.next(timeout=1)
computer is *very* slow
# start 4 worker processes
# evaluate "f(10)"
# prints "100" unless your
# prints "[0, 1, 4,..., 81]"
# prints "0"
# prints "1"
# prints "4" unless your
import time
result = pool.apply_async(time.sleep, (10,))
print result.get(timeout=1)
# raises TimeoutError
© 2009 Fernando NIÑO
38
Python Scientifique
Formation Python
Python - Divers
Rappels
Dates
Fichiers Tar
Persistence
Optimisation
Matplotlib/Mayavi
© 2009 Fernando NIÑO
39
Plot en 3D
# ATTENTION: à invoquer avec ipython -wthread
from numpy import pi, mgrid, sin, cos
from enthought.mayavi import mlab
dphi, dtheta = pi/250.0, pi/250.0
[phi,theta] = mgrid[0:pi+dphi*1.5:dphi,0:2*pi
+dtheta*1.5:dtheta]
m0 = 4; m1 = 3; m2 = 2; m3 = 3; m4 = 6; m5 = 2; m6 =
6; m7 = 4;
r = sin(m0*phi)**m1 + cos(m2*phi)**m3 + sin
(m4*theta)**m5 + cos(m6*theta)**m7
x = r*sin(phi)*cos(theta)
y = r*cos(phi)
z = r*sin(phi)*sin(theta)
# View it.
s = mlab.mesh(x, y, z)
mlab.show()
mlab.savefig('toto.png')
© 2009 Fernando NIÑO
40
Nombres aléatoires - randomex.py
import random
histogram = [0] * 20
# calculate histogram for gaussian
# noise, using average=5, stddev=1
for i in range(1000):
i = int(random.gauss(5, 1) * 2)
histogram[i] = histogram[i] + 1
# print the histogram
m = max(histogram)
for v in histogram:
print "*" * (v * 50 / m)
© 2009 Fernando NIÑO
41
Histogrammes bis
– histogram1.py
import random, pylab
pylab.clf()
l=[]
for i in xrange(10000):
l.append(random.weibullvariate(5,10))
(n,bins,patch)=pylab.hist(l,100)
– histogram2.py
Idem, mais avec une autre distribution aléatoire, avec une
ligne pour best-fit, transparence, titres...
© 2009 Fernando NIÑO
42