IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Optimisation d'une partie de code


Sujet :

Python

  1. #1
    Débutant
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 193
    Points : 58
    Points
    58
    Par défaut Optimisation d'une partie de code
    Bonjour

    Débutant sous python, je souhaiterais savoir s'il est possible d'optimiser une partie d'un code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    a=arange(0.,180.)
    
    b=arange(0.,360.)
    
    
    rows=len(a)
    
    cols=len(b)
    
    #plot_test=array([[0.]*7]*(cols*rows))
    plot_test=array([0.]*(cols*rows))
    
    
    a =flipud(repeat(a,cols))
    
    b =tile(b,rows)
    
    print b, a
    
    
    
    for i in range(0,len(a)):
        cond1 = a[i]>=(tab[:,2])
        
        cond2 = a[i]<(tab[:,8])
        
        cond3 = b[i]>=(tab[:,1])
        
        cond4 = b[i]<(tab[:,3])
        
        cond = cond1 & cond2 & cond3 & cond4
        
        ligne = tab[cond]
    stop


    est il possible d'écrire cette partie de code en rouge sans la boucle for

    merci par avance

    je tiens à préciser que le code marche (je n'ai fourni qu'une partie, il n'y a pas la partie traitement des données qui donne le tab) mais je souhaiterais que ça aille plus vite. A partir d'un test avec une fonction time, c'est la partie en rouge qui est trop lente. Merci

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Points : 102
    Points
    102
    Par défaut
    Je ne sais pas trop ce que tu fais de tes conditions, mais tu dois déjà pouvoir aller plus vite en coupant les tests non nécessaires.

    En faisant quelque chose comme ca, par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    for i in range(0,len(a)):
        if not a[i]>=(tab[:,2]):
            continue
     
        if not a[i]<(tab[:,8]):
            continue
     
        if not b[i]>=(tab[:,1]):
            continue
     
        if not b[i]<(tab[:,3]):
            continue
     
        # Une fois arrivée ici, tu est forcement dans le cas:
        #    cond1 & cond2 & cond3 & cond4.
    Après il faut que tu vois la construction de tes tableaux intermédiaires tab[:,N] ne sont pas factorisable, parce que ca consomme du temps, aussi.

  3. #3
    Débutant
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 193
    Points : 58
    Points
    58
    Par défaut
    merci pour la réponse

    Mais je ne comprends pas comment ddans ce cas comment j'obtiens ma réponse, comment je trouve la ligne de mon tableau qui correspond aux quatre conditions réunies


  4. #4
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    bonjour,

    je ne comprends pas bien ton utilisation de cond. Dans ton programme, cond est un booléen (donc 0 ou 1). tab[cond] c'est vraiment ce que tu souhaites faire ? ou alors c'est tab[i] pour i tel que cond vaille True ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    for i in range(0,len(a)):
        if not a[i]>=(tab[:,2]):
            continue
     
        if not a[i]<(tab[:,8]):
            continue
     
        if not b[i]>=(tab[:,1]):
            continue
     
        if not b[i]<(tab[:,3]):
            continue
     
        break
     
    ligne=tab[i]

  5. #5
    Débutant
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 193
    Points : 58
    Points
    58
    Par défaut
    en faisant mes conditions de 1 à 4 et en faisant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cond= cond1 & cond2 & cond3 & cond 4
    , j'obtiens l'index de la ligne où ces quatre conditions sont true, du coup] me renvoie la ligne qui correspond à ma recherche

    je saisis pas la methode du if not, je vois pas comment toutes mes conditions sur une même de mon tableau seront réunies ensemble.

  6. #6
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    hmm désolé, je me rends compte que ce sont des tableaux numpy.

    connais tu where ?

    http://docs.scipy.org/doc/numpy/refe...mpy.where.html

    ça peut permettre de t'affranchir du for.

  7. #7
    Débutant
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 193
    Points : 58
    Points
    58
    Par défaut
    je me demande s'il est possible d'enlever la boucle for dans la partie du code en rouge, c'est à dire écrire cette partie de code sans une seule boucle pour l'optimiser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    a=arange(0.,180.)
    
    b=arange(0.,360.)
    
    
    rows=len(a)
    
    cols=len(b)
    
    #plot_test=array([[0.]*7]*(cols*rows))
    plot_test=array([0.]*(cols*rows))
    
    
    a =flipud(repeat(a,cols))
    
    b =tile(b,rows)
    
    print b, a
    
    
    
    for i in range(0,len(a)):
        cond1 = a[i]>=(tab[:,2])
        
        cond2 = a[i]<(tab[:,8])
        
        cond3 = b[i]>=(tab[:,1])
        
        cond4 = b[i]<(tab[:,3])
        
        cond = cond1 & cond2 & cond3 & cond4
        
    ligne = tab[cond]
    merci d'avance

  8. #8
    Débutant
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 193
    Points : 58
    Points
    58
    Par défaut
    je connais where, je l'avais déjà utilisé mais sans le for c'est compliqué...et plus long que cette méthode

    je vois pas comment éliminer ce for....

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 99
    Points : 102
    Points
    102
    Par défaut
    Ah okay, vu comment tu utilises ta boucle, j'ai répondu complément a coté :S

  10. #10
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cond = cond1 & cond2 & cond3 & cond4
    On est d'accord que cond vaudra soit 1 soit 0

    Attention à ceci, je vois bien que c'est commenté, mais c'est toujours bon à savoir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #plot_test=array([[0.]*7]*(cols*rows))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> a=[[0]*5]*3
    >>> a
    [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
    >>> a[0][0]=5
    >>> a
    [[5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0]]
    Maintenant, ta requête... sans boucle, je vois pas comment tu veux y arriver (en même temps je ne connais pas Numpy), par contre pour éventuellement réduire le temps d'exécution, tu peux utiliser break, mais surtout xrange (si c'est un gros array) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for i in xrange(0,len(a)):
        ai,bi=a[i],b[i]
        cond=(ai>=(tab[:,2])) & (ai<(tab[:,8])) & (bi>=(tab[:,1])) & (bi<(tab[:,3]))
        if cond : break
    En théorie (je n'ai pas envie d'essayer ) tu pourrais aller plus vite en utilisant deux threads (ou process, c'est à toi de voir), un qui analyserais la première moitié pendant que l'autre analyserais la seconde, chacun faisant donc tourner une fonction qui retournerait True ou False, t'attends que ces deux threads se soient executés, et cond sera égale à un OR logique entre les deux retours de fonctions.

  11. #11
    Débutant
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 193
    Points : 58
    Points
    58
    Par défaut
    merci pour le bout de code

    mais le break stoppe ma boucle

    y'a t'il une solution

    code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for i in xrange(0,len(a)):
        ai,bi=a[i],b[i]
        cond=(ai>=(tab_final_test[:,2])) & (ai<(tab_final_test[:,8])) & (bi>=(tab_final_test[:,1])) & (bi<(tab_final_test[:,3]))
        if cond :
           break
           ligne=tabt[cond]
           print ligne,ai,bi
    message d'erreur :
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
    donc j'ai essayé ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for i in xrange(0,len(a)):
        ai,bi=a[i],b[i]
        cond=(ai>=(tab_final_test[:,2])) & (ai<(tab_final_test[:,8])) & (bi>=(tab_final_test[:,1])) & (bi<(tab_final_test[:,3]))
        if cond.any() == True :
           ligne=tabt[cond]
           print ligne,ai,bi
           break
    mais le break stoppe la boucle et si je l'enlève ça revient à faire la même méthode que cond= cond1 &cnod2&cond3&cond4 donc pas d'optimisation

  12. #12
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Je regrette mais le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    for i in range(0,len(a)):
        cond1 = a[i]>=(tab[:,2])
        cond2 = a[i]<(tab[:,8])
        cond3 = b[i]>=(tab[:,1])
        cond4 = b[i]<(tab[:,3])
        cond = cond1 & cond2 & cond3 & cond4
    ligne = tab[cond]
    fait la chose suivante:

    Pour chacun des i de la succession 0,1,2,3,4.....len)a)-3,len(a)-2,
    il calcule les 4 conditions cond1,cond2,cond3,cond4 ,
    il en déduit la valeur de cond,
    ........et il n’en fait rien.

    Arrivé à la valeur i ==len(a)-1 (c’est la len(a)ième valeur de la succession),
    il calcule les 4 valeurs de cond1,cond2,cond3,cond4 ,
    il en déduit celle de cond,
    et il sort de la boucle.

    Après la boucle il rencontre ligne = tab[cond]:
    il est donc censé affecter à ligne la valeur tab[cond] selon la valeur de cond.

    Cependant, cependant,
    cependant, dis-je:
    les notations tab[:,2],tab[:,8] etc désignent des tableaux unidimensionnels.
    Plus précisément, tab[:,2] est un tableau (au sens numpy, n’est ce pas....) qui est la
    succession des valeurs qu’on trouve dans toutes les rangées de tab à la 3ième colonne (d’indice 2).

    Les comparaisons
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        cond1 = a[i]>=(tab[:,2])
        cond2 = a[i]<(tab[:,8])
        cond3 = b[i]>=(tab[:,1])
        cond4 = b[i]<(tab[:,3])
    n’ont donc de sens que si a[i] et b[i] sont
    - soit des nombres
    - soit des tableaux de longueur égale au nombre de rangées de tab.

    Déjà, arrivé à cet endroit, je trouve que c’est passablement compliqué.

    Mais ensuite:
    quelle que soit la nature (nombre ou tableau) des a[i] et b[i] , le résultat de
    a[i]>=(tab[:,2]) est un tableau
    - de même longueur que le nombre de rangées de tab
    - rempli de False et de True, et rien d’autre

    De même pour a[i]<(tab[:,8]) , b[i]>=(tab[:,1]) et b[i]<(tab[:,3])
    Si bien qu’en définitive, cond est censée être cond1 & cond2 & cond3 & cond4 mais je ne sais pas ce que tableau & tableau donne comme résultat.

    C’est quoi &
    C’est une notation Python qui remplace AND ?
    Ou c’est un opérateur Numpy ?, auquel cas cond1 & cond2 & cond3 & cond4
    donne peut être quelque chose que je ne connais pas.

    Alors donc, je me demande ce que va bien pouvoir être la valeur de tab[cond] qui est censée être affectée à la variable ligne en fonction d’une vérification menée sur la len(a) ième rangée de tab.

    Tu nous dis:
    « en faisant mes conditions de 1 à 4 et en faisant
    cond= cond1 & cond2 & cond3 & cond 4
    , j'obtiens l'index de la ligne où ces quatre conditions sont true, du coup
    tab[cond] me renvoie la ligne qui correspond à ma recherche»
    J’ai de fort doutes que ça se passe vraiment comme tu le dis. À mon avis, ce n’est pas comme ça que tourne ce bout de code. En voulant simplifier l’exposition de ta question, tu l’as rendu incompréhensible.

    Avant d’induire les gens en erreur et de les faire partir dans des idées tarabiscotées ( des threads), il faudrait déjà faire le point sur l’algorithme. Désolé de dire ça, mais si personne ne le fait, qui sait dans quels dédales tu vas te perdre.

    Ou alors je n’ai vraiment rien compris.



    ---------------------------------------

    «tab[cond] me renvoie la ligne qui correspond à ma recherche»
    Mais c’est quoi ta recherche finalement ? Tu cherches quelle ligne ?
    Ne me dis pas que tu es toujours dans le problème de cette file

    http://www.developpez.net/forums/d76...while-if-else/

    .........


    PS

    C'est la phrase de N.tox
    On est d'accord que cond vaudra soit 1 soit 0
    qui m'a fait réfléchir. Je ne sais pas s'il faut t'en remercier ou non

  13. #13
    Débutant
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 193
    Points : 58
    Points
    58
    Par défaut
    pour répondre à tes questions:

    effectivement quand j'ai collé mon code l'indentation s'est mal faite pour la la ligne le code est le suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    a=arange(0.,180.)
     
    b=arange(0.,360.)
     
     
    rows=len(a)
     
    cols=len(b)
     
    #plot_test=array([[0.]*7]*(cols*rows))
    plot_test=array([0.]*(cols*rows))
     
     
    a =flipud(repeat(a,cols))
     
    b =tile(b,rows)
     
    print b, a
     
     
     
    for i in range(0,len(a)):
        cond1 = a[i]>=(tab[:,2])
     
        cond2 = a[i]<(tab[:,8])
     
        cond3 = b[i]>=(tab[:,1])
     
        cond4 = b[i]<(tab[:,3])
     
        cond = cond1 & cond2 & cond3 & cond4
     
        ligne = tab[cond]
     
        plot_test[i]=ligne[0][9]
    je recupère une valeur une fois ma ligne trouvée

    le & equivaut à un and en python

    tab[:,1] est une colonne de mon tableau numpy

    a et b sont des vecteurs de nombres issus des aranges et mises en forme avec le repeat, le tile et le flipud, j'obtiens deux vecteurs de me longueurs, où chaque a[i] et b[i] pour i correspond à un couple de points

    ensuite j'effectue ma recherche avec mes cond (de 1 à 4) qui me renvoie des vecteurs de true ou false de la même longuers que le nombres de lignes dans tab[:,1]

    ensuite le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cond = cond1 & cond2 & cond3 & cond4
    permet d'obtenir un vecteur composé d'un seul true et de false. ce true permet de connaitre la ligne de mon tableau où les quatre conditions sont true ensembles

    ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     cond = cond1 & cond2 & cond3 & cond4
    equivaut à une intersection des quatres vecteurs (cond 1 à 4).

    ma simple question est de savoir si l'on peut faire cette recherche sans faire de boucles for car ça ralentit mon code

    merci

  14. #14
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Bon, je commence à avoir quelques lueurs sur ton nouvel algorithme, et il me semble qu’il va y avoir 2 ou 3 choses à corriger.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    a=arange(0.,180.)
    b=arange(0.,360.)
    rows=len(a)
    cols=len(b)
    plot_test=array([0.]*(cols*rows))
    fait de [0.]*(cols*rows) une liste de 180*360 = 64800 nombres 0.
    et de plot_test un tableau-ligne de 54800 nombres 0.

    1- il y a une instruction spéciale dans Numpy pour créer des tableaux-lignes ou des tableaux-colonnes remplis de 0.

    2- ça me semble a priori bizarre d’avoir besoin d’un tel objet. Il fauda revenir là dessus.




    cond est censée être cond1 & cond2 & cond3 & cond4 mais je ne sais pas ce que tableau & tableau donne comme résultat.
    eyquem
    Excuse moi, j’aurais pu comprendre tout seul comment se calcule cond. Ça relève des calculs logiques impliquant des tableaux Numpy. Il suffit de regarder un tutoriel sur Numpy.




    Je pense que la compréhension de ton algorithme nécessite de comprendre ce que sont a et b.
    a
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     =flipud(repeat(a,cols))
    b =tile(b,rows)
    a et b sont des vecteurs (...) de même longueur
    Je voudrais vérifier que je comprends bien ce que sont a et b.
    Ce sont bien des tableaux-colonnes, de même longueur égale au nombre de lignes (rows) dans le tableau tab, n’est ce pas ?

    Il me semble que cond est une colonne remplie de True et False qui indique par les True les lignes pour lesquelles les 4 conditions sont vérifiées ensembles et qui concenent les nombres aux positions 1,2,3 et 8 de la ligne considérée.

    Par exemple si tab est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    2  7  4  3  10  34  1  64
    1  9  2  6  13  29  4  72
    7  5  3  8  15  28  0  62
    la colonne
    renseigne qu’aux lignes où il y a True
    les conditions tab[:,2]<=63<tab[:,8] et tab[:,1]<=4<tab[:,3] sont vérifiées.

    Est-ce que c’est bien ça : cond est une colonne remplie de True et False de même nombre de lignes que tab ?
    Auquel cas je ne compends toujours pas ce que signifie l’écriture tab[cond].
    tab étant un tableau bidimensionnel, cond étant un tableau-colonne, tab[cond] ça veut dire quoi ??

  15. #15
    Débutant
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 193
    Points : 58
    Points
    58
    Par défaut
    merci pour la réponse

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    2- ça me semble a priori bizarre d’avoir besoin d’un tel objet. Il fauda revenir là dessus.
    je pense que tu as raison on peut le faire avec la fonction zéros...

    a et b sont des vecteurs, soit une ligne, qui ne sont pas égale au nombre de lignes du tableau (environs 300 000 lignes) à mon tableau, a et b comportent 64800 nombres....

    cond est bien une colonne egale aux nombres de lignes de tab

    tab[cond] donne toutes les lignes (affiche les valeurs) où il y a true pour les 4 conditions, dans mon cas une seule ligne correspond à ma recherche

    voilà pour les explications

    je cherche toujours à supprimer ce for pour optimiser ou peut être trouver une autre possibilité pour chercher ma réponse sans utiliser mes conditions....

    j'ai essayé vectorize, le temps de calcul est aussi long

  16. #16
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Bon , j’ai un peu mieux compris ton code. Du moins si a[i] et b[i] sont bien des nombres , et pas des tableaux.

    Je me suis fait un petit code avec un tableau tab et des valeurs a et b en nombre limité pour bien voir ce qu’il se passe.




    Ce n’est pas évident de s’habituer au fonctionnement des tableaux Numpy.
    Si tab est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [[ 0  5 62 16  0  1  1  0 77]
     [ 1 23 61 13  1  1  0  1 75]
     [ 0  7 89 19  1  0  1  1 74]
     [ 0  8 66 18  0  1  1  1 70]
     [ 1  3 62 12  0  0  1  1 68]]
    alors tab[(1,3,4)] n’est pas acceptée
    mais tab[[1,3,4]] renvoit un tableau formé des ligne 1, 3 et 4 de tab:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    [[ 1 23 61 13  1  1  0  1 75]
     [ 0  8 66 18  0  1  1  1 70]
     [ 1  3 62 12  0  0  1  1 68]]


    tab[[True, False, False,True]] est aussi acceptée mais renvoit le tableau formé des lignes 1,0,0 et 1 de tab. Piège



    Par contre,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tab[array([True, False,False,True])]
    renvoit un tableau formé des lignes 0 (premier True) et 4 (deuxième True).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    from numpy import array
    tab = array([[ 0,  5, 62, 16, 0, 1, 1, 0, 77 ],\
                 [ 1, 23, 61, 13, 1, 1, 0, 1, 75 ],\
                 [ 0,  7, 89, 19, 1, 0, 1, 1, 74 ],\
                 [ 0,  8, 66, 18, 0, 1, 1, 1, 70 ],\
                 [ 1,  3, 62, 12, 0, 0, 1, 1, 68 ]])
    print tab[array([True, False, False, True])]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [[ 0  5 62 16  0  1  1  0 77]
     [ 0  8 66 18  0  1  1  1 70]]


    Bon. C’est comme ça hein.



    Mais soit dit en passant, quand tu dis que
    cond est bien une colonne egale aux nombres de lignes de tab
    je suis pas sûr que ce soit bien vrai.

    Pour moi un tableau-ligne c’est ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    from numpy import array
    tab = array([23,45,'suee',1001,786.9,'gargl','ocean'])
    print tab
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ['23' '45' 'suee' '1001' '786.9' 'gargl' 'ocean']
    et un tableau-colonne, c’est ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from numpy import array
    tab = array([23,45,'suee',1001,786.9,'gargl','ocean'])
    tab2 = tab.reshape(7,1)
    print tab2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    [['23']
     ['45']
     ['suee']
     ['1001']
     ['786.9']
     ['gargl']
     ['ocean']]
    Et si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from numpy import array
    tab = array([[ 0,  5, 62, 16, 0, 1, 1, 0, 77 ],\
                 [ 1, 23, 61, 13, 1, 1, 0, 1, 75 ],\
                 [ 0,  7, 89, 19, 1, 0, 1, 1, 74 ],\
                 [ 0,  8, 66, 18, 0, 1, 1, 1, 70 ],\
                 [ 1,  3, 62, 12, 0, 0, 1, 1, 68 ]])
    cond = array([True,False,False,True])
    cond = cond.reshape(4,1)
    print cond
    print tab[cond]
    j’obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [[ True]
     [False]
     [False]
     [ True]]
    [0 0]
    Quant à un vecteur, je ne sais pas ce que c’est.





    Donc , j’en reste sur l’idée que cond est bien un tableau-ligne, malgré ce que tu dis.



    Le code suivant exemplifie ce que fait ton code. Enfin, je pense qu’il fait ça...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    from numpy import array,arange
     
    tab = array([[ 1, 23, 61, 13, 1, 1, 0, 1, 75 ],\
                 [ 0,  5, 62, 16, 0, 1, 1, 0, 77 ],\
                 [ 0,  7, 89, 19, 1, 0, 1, 1, 74 ],\
                 [ 0,  8, 66, 18, 0, 1, 1, 1, 70 ],\
                 [ 1,  3, 62, 12, 0, 0, 1, 1, 68 ]])
     
    print '\ntab =\n',tab
    a = (10, 108, 11, 11)
    b = (67,  73, 71, 69)
     
    for i in xrange(4):
        print '\n\n-------- a[i] = '+str(a[i])+'  #  b[i] = '+str(b[i])+' -------\n'
     
        cond1 = tab[:,1] <= a[i]
        cond3 = a[i] < tab[:,3]
     
        cond2 = tab[:,2] <= b[i]
        cond8 = b[i] < tab[:,8]
     
        cond = cond1 & cond2 & cond3 & cond8
     
        print 'cond1 =',cond1
        print 'cond3 =',cond3
        print 'cond2 =',cond2
        print 'cond8 =',cond8
        print 'cond  =',cond
     
        print '\ntab[cond} =\n',tab[cond]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    tab =
    [[ 1 23 61 13  1  1  0  1 75]
     [ 0  5 62 16  0  1  1  0 77]
     [ 0  7 89 19  1  0  1  1 74]
     [ 0  8 66 18  0  1  1  1 70]
     [ 1  3 62 12  0  0  1  1 68]]
     
     
    -------- a[i] = 10  #  b[i] = 67 -------
     
    cond1 = [False  True  True  True  True]
    cond3 = [ True  True  True  True  True]
    cond2 = [ True  True False  True  True]
    cond8 = [ True  True  True  True  True]
    cond  = [False  True False  True  True]
     
    tab[cond} =
    [[ 0  5 62 16  0  1  1  0 77]
     [ 0  8 66 18  0  1  1  1 70]
     [ 1  3 62 12  0  0  1  1 68]]
     
     
    -------- a[i] = 108  #  b[i] = 73 -------
     
    cond1 = [ True  True  True  True  True]
    cond3 = [False False False False False]
    cond2 = [ True  True False  True  True]
    cond8 = [ True  True  True False False]
    cond  = [False False False False False]
     
    tab[cond} =
    []
     
     
    -------- a[i] = 11  #  b[i] = 71 -------
     
    cond1 = [False  True  True  True  True]
    cond3 = [ True  True  True  True  True]
    cond2 = [ True  True False  True  True]
    cond8 = [ True  True  True False False]
    cond  = [False  True False False False]
     
    tab[cond} =
    [[ 0  5 62 16  0  1  1  0 77]]
     
     
    -------- a[i] = 11  #  b[i] = 69 -------
     
    cond1 = [False  True  True  True  True]
    cond3 = [ True  True  True  True  True]
    cond2 = [ True  True False  True  True]
    cond8 = [ True  True  True  True False]
    cond  = [False  True False  True False]
     
    tab[cond} =
    [[ 0  5 62 16  0  1  1  0 77]
     [ 0  8 66 18  0  1  1  1 70]]

    Donc tab[cond] sort bien une liste de lignes de tab pour lesquelles les 4 conditions sont vérifiées.

    En fait, ce code fait la même chose que le code que j’avais proposé dans la discussion que j’ai citée plus haut.
    Sauf que cette fois, il sort les lignes qui s’allument pour un couple a[i],b[i] et il itère sur i pour sortir ces lignes pour tous les couples d’une succession a[i],b[i] repérés par i.



    —--------------------------------

    Tu dis cependant:

    cond = cond1 & cond2 & cond3 & cond4
    permet d'obtenir un vecteur composé d’UN SEUL true et de false
    tab[cond] donne toutes les lignes (affiche les valeurs) où il y a true pour les 4 conditions, dans mon cas une seule ligne correspond à ma recherche
    Tes valeurs dans tab et dans a et b doivent donc être bien particulières pour qu’il n’y ait pour chaque i qu’UNE SEULE LIGNE qui réponde aux conditions.

    J’espèe que c’est effectivement ainsi, parce que dans ce cas, ton code tourne correctement mais il est mal conçu, et donc peut être optimisé

    En effet, il perd beaucoup de temps à des calculs inutiles.



    Regardons ce qui se passe par exemple avec mon code pour a=11 et b = 71.

    Le progamme commence par calculer cond1 = tab[:,1] <= 11
    Comme la colonne 1 de tab est
    23
    5
    7
    8
    3
    cond 1 va être [False True True True True]

    Dès ce moment, on sait donc que la première ligne ne sera pas la bonne puisque sa valeur en t[1,1] est 23>11 qui donne 23<=11 = False.

    Pourtant, malgré cette infomation, à l’instruction suivante, le programme calcule cond3 = 11 < tab[:,3] meme pour la première ligne
    La colonne 3 est
    13
    16
    19
    18
    12
    et cond2 calculée est [True True True Tue True] c’est à dire que le programme évalue bien que 11<13 à la première ligne , alors qu’on sait que cette ligne n’est pas bonne.


    Pour cond2 = tab[:,2] <= 71, il refait pareil:
    La colonne 2 est
    61
    62
    89
    66
    62
    et il évalue inutilement si 61<=71 pour la première ligne.
    À 61<89, il y a False qui sort pour la 3ième ligne.

    Malgré les deux informations obtenues en cond1 et cond2,
    pour le calcul de cond8 = 71 < tab[:,8] sur la colonne 8
    75
    77
    74
    70
    68
    le programme va quand même évaluer inutilement 71<75 pour la première ligne et 71<74 pour la troisième ligne.



    On voit donc que calculer les valeurs condX pour les quatre colonnes 1,2,3,8 et regarder APRÈS là où il y a des True n’est même pas un bon algorithme même si on cherchait plusieurs lignes.

    Car en faisant l’inverse, prendre les lignes l’une après l’autre, pemettrait, pour une ligne donnée, de n’être obligé de faire les 4 tests sur les valeurs des 4 colonnes 1,2,3,8 sur cette ligne que si les 3 premiers tests étaient True et de s’arrêter au contraire dès que l’un des tests donnerait False.

    Ce qui correspond à l’idée de shadowsam dans le message #2.



    En outre, dans ton cas particulier dans lequel tu dis qu’il n’y a qu’une seule ligne qui doit sortir pour chaque couple a[i],b[i],
    ton algorithme signifie que tu fais faire des calculs à ton programme même pour des lignes qui sont situées plus bas que la ligne recherchée.
    Il travaille donc inutilement sur un plus ou moins grand nombre de lignes: ça dépend de la position de la bonne ligne dans le tableau pour chaque couple ai,bi.
    Mais ça, ça se répète pour CHAQUE i. Ça ralentit à mon avis considérablement.



    ---------------------------------


    Pour diviser le temps d’exécution par 10 ou même par 100, il faut à mon avis



    1/ reprendre mon code du message #10 ici
    http://www.developpez.net/forums/d76...while-if-else/
    et l’injecter dans ton code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    lin,col = tab.shape
    for i in range(0,len(a)):
     
        for ln in tab:
            if b[i]>=ln[1] and  b[i]<ln[3] and a[i]>=ln[2] and  a[i]<ln[8] :
                plot_test[i]=ln[0][9]
                break
    Remarque:
    dans plot_test[i]=ligne[0][9] je ne comprends pas le sens de [0][9] si ligne est une ligne du tableau tab



    2/ En Python, quand on fait faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a[i]= 11  b[i]=71
    if a[i]>=7 and  a[i]<19 and b[i]>=89 and  b[i]<74:
    le programme teste d’abord a[i]>=7 , puis a[i]<19 et fait and, puis teste b[i]>=89 ....et ne va pas plus loin parce que b[i]>=89 est False.

    Si False sort pour la première évaluation a[i]>=7, c’est 3 évaluations subséquentes qui ne sont pas faites, donc autant de gagné en temps.

    C’est à dire qu’en écrivant ainsi ( et non pas en forçant le programme à calculer cond1 et cond2 et cond3 et cond 4 avant de les réduire ), le programme s’arrête d’évaluer une ligne dès qu’il constate qu’une des 4 valeurs ne vérifie pas son critère.



    DONC,

    tu as intérêt à analyser ton tableau pour voir si l’une des colonnes 1,2,3,8 est plus densément remplies de valeurs qui ne vérifient pas son critère que les autres colonnes.
    En mettant le test sur cette colonne en première position dans le if,
    par exemple if a[i]>=ln[2] and b[i]>=ln[1] and b[i]<ln[3] and a[i]<ln[8] : si c'est la colonne 2,
    cela fera gagner du temps car le programme abandonnera l’examen d’une ligne en moyenne plus rapidement sur les lignes non OK.


    ------------------------------------------

    Si tu veux te convaincre de l’efficacité de ce genre de changements, tu peux aller voir ici:
    http://www.developpez.net/forums/d75...e/#post4375618
    un problème impliquant semblablement des calculs sur des tableaux Numpy.

    Bien que je ne me rappelle plus précisément le problème, je sais qu’en changeant l’algorithme, j’ai réussi à diviser par 10 le temps d’exécution. Ça c’est pour la solution que j’ai postée. Parce qu’en poussant encore les améliorations je suis arrivé à descendre le temps d’exécution à 3 ou 1 %, même moins je crois, du temps de 10h annoncé par l’auteur du problème. Ce qui représente un passage de 10 heures à 6 minutes quand même.

  17. #17
    Débutant
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 193
    Points : 58
    Points
    58
    Par défaut
    Merci pour la réponse eyquem

    a[i] et b[i] sont des nombres effectivement et pour peut être aidé, cela correspond à un couple de coordonnées, la colonne 1 de mon tab correspond à la longitude min, la 2 à la latitude min, la 3 à la longitude max et la 8 à la latitude max

    mon cond renvoie une tableau ligne ou vecteur si tu veux, qui comprend autant de true et false que de lignes de mon tableau....mais avec un seul true qui correspond à ma recherche suivant les lat et lon

    ce qui m'intéresse c'est récupérer les valeurs associées à cette ligne, les valeurs à partir de la colonne 9...

    il y a donc une seule ligne et je suis conscient que c'est pas la bonne solution, j'ai commencé python il y a pas longtemps....l'idéal serait de stopper la boucle dés que j'ai trouvé la réponse

    il y a peut être une solution qui pourrait m'aider, les valeurs de mes colonnes 2 et 8 sont dans un ordre croissant je vais voir avec searchsorted si je peux m'en servir....

    j'ai essayé le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    lin,col = tab.shape
    for i in range(0,len(a)):
     
        for ln in tab:
            if b[i]>=ln[1] and  b[i]<ln[3] and a[i]>=ln[2] and  a[i]<ln[8] :
                plot_test[i]=ln[0][9]
                break
    il est plus lent que la recherche par les 4 conditions...

    je me penche dessus si je trouve des pistes je les soumettrai

    peut être qu'aprés chaque condition je devrai faire ma condition suivante seulement sur les true de la condition précédente et ainsi de suite... je réduirai mon champ de recherche dans mon tab à chaque fois pour tomber sur la bonne ligne...

    merci pour tout

  18. #18
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    il est plus lent que la recherche par les 4 conditions...
    Cela m’a beaucoup surpris de lire ça.
    J’ai vérifié. Et effectivement mon algorithme est plus lent.

    J’ai même fait le code suivant pour bien voir: il met en évidence que ta méthode avec les tableaux est d’autant plus rapide que le tableau exploré est grand.
    J’ai pris les données que tu avais fournies dans le message #11 ici
    http://www.developpez.net/forums/d76...while-if-else/
    pour faire deux listes:
    libase contient 20 lignes de ton tableau ne répondant pas au critère des 4 conditions
    lifin contient une ligne qui vérifie ces conditions, plus une dernière pour faire joli.
    k*libase + lifin est une liste d’autant plus grande que k est grand, et la ligne recherchée se trouve de plus en plus loin du début

    Ensuite il suffit de créer le tableau tab = array(k*libase + lifin) pour pouvoir comparer les 2 types de recherche sur des tableaux dans lesquels la bonne ligne est de plus en plus loin

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    from numpy import array,arange
    from time import clock
     
    libase = [[ 201., 352.34 ,1.75, 360., 1.75, 360.,
                2. ,352.34 ,2., -1., -1. ,
                -1. ,-1. ,-1. ,-1., -1. ],
     
              [ 202., 0. ,2.,6.79245, 2., 6.79245,
                2.25 ,0. ,2.25, 0.84899998 ,0.69099998,
                0.84899998 ,0.85100001,0.72899997 ,0.833 ,0.76200002],
     
              [ 203. ,6.79245 ,2. ,13.5849 ,2.,13.5849,
                2.25, 6.79245 ,2.25, 0.84899998, 0.69499999,
                0.85000002 ,0.85399997, 0.736 ,0.83600003 ,0.76899999],
     
              [ 202., 0. ,2.,6.79245, 2., 6.79245,
                2.25 ,0. ,2.25, 0.84899998 ,0.69099998,
                0.84899998 ,0.85100001,0.72899997 ,0.833 ,0.76200002],
     
              [ 203. ,6.79245 ,2. ,13.5849 ,2.,13.5849,
                2.25, 6.79245 ,2.25, 0.84899998, 0.69499999,
                0.85000002 ,0.85399997, 0.736 ,0.83600003 ,0.76899999],
     
              [ 204., 13.5849 ,2., 20.3774 ,2. ,20.3774,
                2.25 ,13.5849, 2.25, 0.85100001 ,0.69800001,
                0.85299999, 0.85900003 ,0.73900002 ,0.84299999 ,0.77399999],
     
              [ 205., 20.3774 ,2. ,27.1698 ,2., 27.1698,
                2.25, 20.3774 ,2.25 ,0.84399998 ,0.69099998,
                0.847 ,0.85900003 ,0.741, 0.85399997 ,0.78100002],
     
              [ 206. ,27.1698, 2., 33.9623 ,2.,33.9623,
                2.25 ,27.1698 ,2.25, 0.84200001 ,0.68699998,
                0.84600002, 0.86199999 ,0.74299997, 0.86000001, 0.78799999],
     
              [ 207., 33.9623 ,2., 40.7547, 2., 40.7547,
                2.25, 33.9623, 2.25, 0.838 ,0.67799997,
                0.83999997, 0.85799998 ,0.73100001 ,0.85699999, 0.78100002],
     
              [ 208., 40.7547, 2. ,47.5472 ,2. ,47.5472,
                2.25,40.7547, 2.25 ,0.83999997, 0.676,
                0.84100002 ,0.85600001, 0.72399998 ,0.85500002 ,0.77700001],
     
              [ 209. ,47.5472, 2., 54.3396 ,2., 54.3396,
                2.25, 47.5472 ,2.25, 0.84600002 ,0.68000001,
                0.84500003 ,0.85100001 ,0.72500002 ,0.83999997 ,0.76899999],
     
              [ 210. ,54.3396, 2., 61.1321,2., 61.1321,
                2.25 ,54.3396, 2.25, 0.84200001 ,0.67799997,
                0.838, 0.84100002, 0.71399999, 0.83499998,0.75700003],
     
              [ 212. ,67.9245, 2. ,74.717, 2. ,74.717,
                2.25 ,67.9245 ,2.25 ,0.85100001, 0.69099998,
                0.84600002, 0.84799999, 0.71899998, 0.83899999, 0.76200002],
     
              [ 213. ,74.717, 2., 81.5094, 2. ,81.5094,
                2.25 ,74.717 ,2.25, 0.86799997 ,0.70999998,
                0.86299998 ,0.86500001, 0.736, 0.85100001 ,0.778 ],
     
              [ 214. ,81.5094, 2., 88.3019 ,2., 88.3019,
                2.25, 81.5094 ,2.25 ,0.86299998 ,0.71100003,
                0.86000001 ,0.86199999, 0.73799998 ,0.84200001 ,0.77100003],
     
              [ 215. ,88.3019, 2. ,95.0943, 2. ,95.0943,
                2.25 ,88.3019 ,2.25 ,0.86699998 ,0.72000003,
                0.86299998 ,0.86400002 ,0.74699998 ,0.82800001 ,0.76099998],
     
              [ 216., 95.0943, 2., 101.887 ,2. ,101.887,
                2.25, 95.0943, 2.25, 0.86500001, 0.72500002,
                0.86199999 ,0.86500001, 0.75 ,0.83499998 ,0.764 ],
     
              [ 217. ,101.887 ,2. ,108.679 ,2., 108.679,
                2.25 ,101.887, 2.25 ,0.86299998 ,0.727, 0.861,
                0.86400002, 0.75300002, 0.84500003 ,0.77100003],
     
              [ 218. ,108.679 ,2., 115.472, 2., 115.472,
                2.25 ,108.679 ,2.25 ,0.86699998, 0.73400003,
                0.86500001 ,0.866, 0.75999999, 0.83700001 ,0.76700002],
     
              [ 219. ,115.472, 2. ,122.264, 2. ,122.264,
                2.25, 115.472, 2.25, 0.85900003, 0.73000002,
                0.85699999 ,0.85900003, 0.75599998, 0.833, 0.76599997]]
     
     
     
    lifin  = [[ 211. ,61.1321 ,2. ,67.9245 ,2. ,67.9245,
                2.25 ,61.1321, 2.25, 0.84600002, 0.68400002,
                0.84100002 ,0.84200001 ,0.71600002 ,0.83600003, 0.75999999],
     
              [ 220. ,122.264, 2. ,129.057, 2., 129.057,
                2.25 ,122.264 ,2.25 ,0.85600001, 0.72600001,
                0.85500002, 0.85799998, 0.75599998 ,0.83700001 ,0.77200001]]
     
     
    def eyqu(tab,b,a):
        lin,col = tab.shape
        for ln in tab:
            if b>=ln[1] and  b<ln[3] and a>=ln[2] and  a<ln[8] :
                return
     
    def niep(tab,b,a):
        cond1 = tab[:,1] <= b
        cond3 = b < tab[:,3]
        cond2 = tab[:,2] <= a
        cond8 = a < tab[:,8]
        cond = cond1 & cond2 & cond3 & cond8
        return
     
     
    for k in (1,5,10,20,50,100,500,1000,10000):
        li = k*libase + lifin
        print '\nk =',k,'  len(li) =',len(li)
        tab = array(li)
     
        te = clock()
        eyqu(tab,63,2.1)
        tf = clock()
        dey = tf-te
        print dey
     
        te = clock()
        niep(tab,63,2.1)
        tf = clock()
        dni = tf-te
        print dni
        print 'temps niep / temps eyqu =',dni/dey
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    k = 1   len(li) = 22
    0.000691428659223
    0.000588901662084
    temps niep / temps eyqu = 0.851717171726
     
    k = 5   len(li) = 102
    0.00284617179
    0.000439720690764
    temps niep / temps eyqu = 0.154495484886
     
    k = 10   len(li) = 202
    0.00559735944094
    0.000490285776536
    temps niep / temps eyqu = 0.0875923337976
     
    k = 20   len(li) = 402
    0.0111614744332
    0.000534425464693
    temps niep / temps eyqu = 0.0478812604814
     
    k = 50   len(li) = 1002
    0.0285458067995
    0.000793396926142
    temps niep / temps eyqu = 0.0277938168543
     
    k = 100   len(li) = 2002
    0.0576936454214
    0.0013702858883
    temps niep / temps eyqu = 0.0237510713405
     
    k = 500   len(li) = 10002
    0.284537839306
    0.00495817205818
    temps niep / temps eyqu = 0.0174253521791
     
    k = 1000   len(li) = 20002
    0.569961545392
    0.00820467405774
    temps niep / temps eyqu = 0.0143951361703
     
    k = 10000   len(li) = 200002
    6.16494051618
    0.0829700422819
    temps niep / temps eyqu = 0.0134583686678

    Le résultat est donc exactement inverse de celui que j’attendais ! Ton algorithme va jusqu’à donner une vitesse 100 fois moindre.
    Félicitations.





    Disons plutôt, félicitation à Numpy:
    je pense que l’explication est que les calculs sur des tableaux Numpy sont très rapides et optimisés. Lu sur plusieurs sites. Si rapides donc qu’ils font plus que compenser l’inconvénient algorithmique.
    Je lis dans le Hors Série de Linux Magazine de Janvier 09 consacré à Python:
    Ces fonctions sont implémentées directement en C, et sont donc très rapides sur de gros tableaux.
    Phrase suivante:
    une bonne règle à suivre pour faire du code effcicae et lisible avec Numpy est de bannir les boucles for et de manipuler un tableau comme un tout
    - Je pense donc que quelqu’un habitué à utiliser Numpy devrait pouvoir trouver comment éliminer ta boucle pour produire directement un tableau contenant les résultats voulus (valeurs en colonne 9). Ça m’intéresserait de creuser mais je n’ai pas le temps. Je suis persuadé que les possibilités étendues de jouer sur les indices dans Numpy doivent permettre de sélectionner autrement les 4 colonnes que par 4 écritures séparées
    Tu ferais peut être bien de reposter ta question dans le sous-forum ’Calcul scientifique’ ou un forum spécifique consacrè à Numpy


    - Je te soumets aussi une idée:
    l’ensemble des conditions
    ln[1] <= b
    b < ln[3]
    ln[2] <= a
    a < ln[8]
    est équivalent à l’ensemble
    0 <= b - ln[1]
    0 < ln[3] - b
    0 <= a - ln[2]
    0 < ln[8] - a

    Si tu as la possibilité de modifier les conditions pour ne te retrouver qu’à vérifier
    0 < b - ln[1]
    0 < ln[3] - b
    0 < a - ln[2]
    0 < ln[8] -a
    tu pourrais tester d’un coup le tableau
    tsous = [b - ln[1] ln[3] - b a - ln[2] ln[8] -a ]:

    if tsous > 0:


    - Autre idée:
    utiliser scipy.weave pour coder la partie centrale de mon algorithme sous forme de code C++ inclus directement dans le code Python sous forme de chaîne de caractères.
    J'ai lu cette possibilité dans le même magazine Hors Série


    - Enfin, psyco est un module qui parait-il permet d'augmenter la vitesse d'un programme.[/I][/I]







    Pa r curiosité, pourrais tu indiquer la taille du tableau que tu explores et les temps que tu obtiens ,stp ?

    Pourquoi cherches-tu à optimiser ? Ce n’est peut être pas possible de decendre plus bas si ton tableau est énorme. Il y a des limites à tout.

  19. #19
    Débutant
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 193
    Points : 58
    Points
    58
    Par défaut
    j'ai trouvé une solution pour mon optimisation, je suis passé de 105 minutes à 19 secondes..........

    voilà le code, j'ai abandonné l'idée de mes vecteurs donnés avec tile, repeat et filpud........

    plus simple à faire en plus.......

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    resol=1
    a=arange(0.,180.,resol)
     
    b=arange(0.,360.,resol)
     
    rows=len(a)
     
    cols=len(b)
     
    plot_test=array([[0.]*7]*(cols*rows))
     
    i=-1
     
    for val in a :
     
        cond1 = (val>=(tab[:,2]))&(val<(tab[:,8]))
     
        tab_n=tab[cond1]
     
        for val_l in b :
            i+=1
            cond3 = (val_l>=(tab_n[:,1]))&(val_l<(tab_n[:,3]))
     
            ligne = tab_n[cond3]
     
            plot_test[i][:]=ligne[0][9:]
    l'idée est de réduire le tableau aprés la première condition pour faciliter la recherche de la condition suivante....

    voilà je suis preneur, si vous trouvez mieux, surtout pour éliminer cette double boucle for...ça ralentit en python et je serai curieux d'apprendre en plus....j'ai utlisé vectorize de numpy, pas efficace

    pour répondre à eyquem, mon tableau fait 600 000 lignes environs...pour 16 colonnes

  20. #20
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Pas très compréhensible



    tab[:,2]

    tabt[:,8]

    tab_n=tabt[cond1] se retrouve dans tab_n[:,1]

    tab_nt[:,3]

    et ligne = tab_lat

    Ça en fait des tableaux différents. Il y en a vraiment autant ?



    Mais si ça te donne le résultat voulu, il reste à applaudir, parce que un temps divisé par 331, faut le faire.

Discussions similaires

  1. Réponses: 9
    Dernier message: 03/07/2007, 11h44
  2. comprendre une partie du code
    Par mademoizel dans le forum ASP.NET
    Réponses: 4
    Dernier message: 09/02/2007, 11h40
  3. comprendre une partie de code
    Par menuge dans le forum Langage
    Réponses: 24
    Dernier message: 03/09/2006, 20h44
  4. une partie du code a disparu
    Par recup dans le forum Balisage (X)HTML et validation W3C
    Réponses: 9
    Dernier message: 08/03/2005, 10h08
  5. Indenter une partie du code
    Par KooX dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 23/05/2004, 17h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo