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(<ime); return ctime(<ime); } © 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