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 :

calcul du plus grand nombre


Sujet :

Python

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    321
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 321
    Points : 109
    Points
    109
    Par défaut calcul du plus grand nombre
    Bonjour,

    je débute un peu en python et je cherche un moyen de calculer un rang de valeur(1,2,3..) par rapport à des pourcentage dédié à un critère.
    j'ai plusieurs pourcentage pour un critère et j'aimerais insérer dans un nouveau champ(mon calcul se base sur celui ci) des valeurs qui corresponde à

    le % le plus élévé pour ce critère est rang1 , le second rang 2 et ainsi de suite.

    Comment incrémenter cette valeur de rang pour cess différents critère?

    merci de votre aide

  2. #2
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Je n'ai strictement rien compris à ce que tu veux faire !
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    321
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 321
    Points : 109
    Points
    109
    Par défaut
    j'ai deux liste,
    -une liste de métier (....)
    -une liste de pourcentage
    chaque métier correspond à plusieurs %
    j'aimerais attribuer une valeur de rang (1,2,3..) en fonction de l'importance de ce %.
    métier1 >>>(5%,10%)
    10% correspond à rang : 1
    5%corrspond à rang: 2

  4. #4
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    toujours pas, même en y mettant de la bonne volonté !

    C'est quoi ces "rangs" ? indice du pourcentage dans la liste des pourcentages ?
    Où est l'info "tel métier est lié à tels pourcentages" ?
    etc ...

    les infos que tu donnes sont trop vagues et incomplètes
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    321
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 321
    Points : 109
    Points
    109
    Par défaut
    rang(classement des valeurs de la plus grande à la plus petite ici ces valeurs sont les pourcentages)

    ces infos sont rattachés dans une table attributaire
    Une colonne métier et une colonne %
    dans une 3ème colonne (rang) je cherche à insérer automatiquement ces valeurs de rang (1,2,3..)

    metier % region rang
    pêcheur 10 ..... 1
    pêcheur 20 ...... 2
    agriculteur 15 ....... 1
    agriculteur 10 ..... 2

  6. #6
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Citation Envoyé par plxpy Voir le message
    Je n'ai strictement rien compris à ce que tu veux faire !
    Moi non plus. C'est dommage, un problème bien énoncé est quasiment résolu.

    A+

    Pfeuh

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

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Points : 224
    Points
    224
    Par défaut
    edit : au vu du message #5 que je n'avais pas vu, c'est pas ce que je pensais. J'enlève mon message.
    C'est vraiment pas clair.

    Si tu veux classer des valeurs, regarde la fonction sorted() et ou la méthode de liste sort()
    http://http://wiki.python.org/moin/HowTo/Sorting/

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    321
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 321
    Points : 109
    Points
    109
    Par défaut
    je devrais parler du logiciel que j'utilise avant tout: c'est arcgis
    c'est un logiciel de cartographie où est inclus un module python
    j'ai des tables attributaires reliés à une géométrie (cf pièces jointes)

    j'ai regardé ton lien valAa, c'est pas tout à fait cela en effet
    effort_maille>> c'est mes %
    j'ai plusieurs % au sein d'un même code maille
    j'aimerais classer ces pourcentages pour chaque code_maille par ordre de grandeur (de 1 à...)

    merci
    Images attachées Images attachées  

  9. #9
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 049
    Points : 1 380
    Points
    1 380
    Par défaut
    metier % region rang
    pêcheur 10 ..... 1
    pêcheur 20 ...... 2
    agriculteur 15 ....... 1
    agriculteur 10 ..... 2


    c'est quoi les critères ?

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    321
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 321
    Points : 109
    Points
    109
    Par défaut
    le code_maille sur la pj et ce code correspond à une région

  11. #11
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 049
    Points : 1 380
    Points
    1 380
    Par défaut
    posons la question autrement ...
    si mériter vaut X et région vaut Y, combien vaut rang ?

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    321
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 321
    Points : 109
    Points
    109
    Par défaut
    le rang se définit par rapport au pourcentage(effort_maille).
    pour une région >>j'ai un métier, un pourcentage

    j'ai région=[palangre,tremail,nasse]
    "palangre" (un métier)= [10,5,2,7] (valeur de pourcentage)

    le rang de "palangre"[10]=1
    "palangre"[7]=2
    ....
    ce n'est pas l'index que je veux obtenir, mais trier les valeurs de pourcentage et incrémenter dans le champ "rang" une valeur qui me permettrait de les classer du plus grand au plus petit(de 1 à 4 pour le palangre).

  13. #13
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Je crois comprendre, mais pour une réponse plus complète, j'ai une petite question.

    Pour une entrée (cf ta pièce jointe) qui a cette allure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Métier    Effort maille    Maille    Rang
    ..........                 101
    palangre   0.9             102        0
    tremail    0.5             102        0
    ..........                 103
    tu souhaites obtenir ça (les rangs sont calculés pour une maille) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Métier    Effort maille    Maille    Rang
    ..........                 101
    palangre   0.9             102        1
    tremail    0.5             102        2
    ..........                 103
    ou ça (les rangs sont calculés pour les couples (maille,métier)) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Métier    Effort maille    Maille    Rang
    ..........                 101
    palangre   0.9             102        1
    tremail    0.5             102        1
    ..........                 103
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    321
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 321
    Points : 109
    Points
    109
    Par défaut
    oui c'est la première proposition
    "tu souhaites obtenir ça (les rangs sont calculés pour une maille) :"

    suis désolé ,j'était tellement dans les tuto python toute la journée que j'ai le cerveau qu a cramé
    en me relisant (aprés une bonne pause) je comprend a quelle point je n'était pas très clair

    merci

  15. #15
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Il y a 2 aspects dans ce que tu veux faire.

    Tu dois :

    1 - causer avec ArcGIS : lire/récupérer tes objets (objets géographiques, pas objets au sens POO) et les "réécrire" une fois que tu auras déterminé ces fameux "rangs"

    2 - mettre à jour les objets géographiques en calculant leur "rang"


    Côté ArcGIS, tu dois te référer à la documentation fournie pour savoir comment et sous quelle forme tu récupères tes objets.

    Je connais un peu ArcGIS, pas trop l'interface Python proposée, mais je ne pense pas prendre beaucoup de risque en imaginant qu'une fonction te permettra d'effectuer une requête (en précisant la classe d'objets voulue, telle ou telle condition sur tel ou tel attribut, une zone géographique, etc...) et de récupérer tes objets (une liste d'objets).

    Quelle forme (Python) auront-ils ? des instances d'une classe "ArcGISFeature" ? des tuples ou des dictionnaires regroupant la géométrie et les attributs de chaque objet ? autre chose ? Là aussi, réfère-toi à la doc.

    Côté "Python pur", à partir de ta liste (unique) d'objets géographiques, il faut que :

    - tu construises autant de listes qu'il y a de mailles (tu classes les "métiers" dans chacune des mailles) avec les objets géographiques localisés dans une même maille
    - tu appliques un tri basé la valeur de "effort maille" (tri inversé car tu veux en premier la plus forte valeur) voir cette discussion récente
    - dans chaque liste, tu affectes le rang de chaque objet en fonction de sa position dans la liste triée (1 pour le premier, 2 pour le deuxième, etc...)

    Après tu dois "faire prendre en compte" les changements effectués sur tes objets à ton "projet" ArcGIS (écriture ? sorte de "commit" ? voir la doc).


    Sans connaître finement l'interface Python proposée par ArcGIS (les modules, les classes, les fonctions), je ne peux pas être plus précis.



    ps : à lire ce billet concernant les SIG (dont ArcGIS) et la façon dont ils (mal)traitent Python
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    321
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 321
    Points : 109
    Points
    109
    Par défaut
    merci de ta réponse!
    Oui effectivement les différences sur python pour les sig est dommage car je ne sais pas quel tuto aborder.
    Mais bon j'ai peut être trouvé deux fonctions qui peuvent répondre à mon problème

    http://help.arcgis.com/fr/arcgisdesk...003m000000.htm
    et
    http://help.arcgis.com/fr/arcgisdesk...0000039000000/

  17. #17
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Autant tirer parti du fait que l'on peut demander un curseur trié.
    Quelque chose comme ceci conviendrait, il me semble:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # ouvrir un UpdateCursor, reprenant les champs code_maille, effort_maille et rang, trié sur code_maille et sur effort_maille descendant
    rows = arcpy.UpdateCursor(...)
    maille_courante = None
    for row in rows:
        if maille_courante == row.code_maille:
            rank += 1
        else:
            rank = 1
        row.rang = rank
        rows.updateRow(row)
    del row
    del rows
    Cela vaudrait sans doute la peine d'implémenter un context_manager pour rendre un peu plus propre la gestion du curseur...

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    321
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 321
    Points : 109
    Points
    109
    Par défaut
    ok merci!

    tu peux m'expliquer ce qu'est un context manager? stp

  19. #19
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Attention il faut un peu s'accrocher

    Le problème est que le code ci-dessus n'est pas sûr. En me référant à la doc, je lis qu'un verrou exclusif est mis sur la table quand un UpdateCursor est ouvert. Si une exception se produit, par exemple lors de la mise à jour d'une ligne, le "del row; del rows" n'est pas exécuté et le verrou n'est pas libéré, ce qui rend la table inutilisable (jusqu'à la fin du processus).
    La seule façon que je vois pour justifier ce que dit la doc est qu'une méthode __del__ est définie sur les classes Cursor et Row. En soi c'est déjà un choix discutable...

    Un meilleur code est celui-ci:
    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
    # ouvrir un UpdateCursor, reprenant les champs code_maille, effort_maille et rang, trié sur code_maille et sur effort_maille descendant
    rows = arcpy.UpdateCursor(...)
    try:
        row = None
        maille_courante = None
        for row in rows:
            if maille_courante == row.code_maille:
                rank += 1
            else:
                rank = 1
            row.rang = rank
            rows.updateRow(row)
    finally:
        if row: del row
        del rows
    Le try/finally permet de s'assurer que le code dans la partie 'finally' est toujours exécuté, même si l'exécution est interrompue par une exception.

    Mais écrire ce try/finally à chaque fois que l'on veut manipuler la DB est un peu barbant et facile à oublier. Un context manager permet de simplifier cela:
    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
    from contextlib import contextmanager
     
    @contextmanager
    def update_cursor(*args):
        r = arcpy.UpdateCursor(*args)
        yield r
        del r
     
    # ouvrir un UpdateCursor, reprenant les champs code_maille, effort_maille et rang, trié sur code_maille et sur effort_maille descendant
    with update_cursor(...) as rows:
        row = None
        maille_courante = None
        try:
            for row in rows:
                if maille_courante == row.code_maille:
                    rank += 1
                else:
                    rank = 1
                row.rang = rank
                rows.updateRow(row)
        finally:
            if row: del row
    On a remplacé l'appel direct à UpdateCursor par un appel à update_cursor. Dans update_cursor, la partie avant le yield est exécutée avant le corps du "with", le yield passe la main au corps du "with" et la partie après le yield correspond au "finally".

    Mais on n'a que peu gagné car ici c'est relativement complexe; d'après la doc, il faut s'assurer de libérer à la fois le curseur (rows) et la ligne actuelle (row), et le context manager ne s'occupe que du curseur lui-même. Il ne peut en effet pas s'occuper de "row" vu que celle-ci n'est instanciée que plus tard et n'est pas encore connue. Il reste donc un try/finally pour s'occuper de "row".

    Pour améliorer les choses, il faut donc se passer du décorateur (@contextmanager) et écrire un gestionnaire de contexte "à la main", qui sera aussi un proxy pour le curseur afin de protéger les "rows":
    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
     
    class SafeUpdateCursor(object):
        def __init__(self, *args):
            self.cur = arcpy.UpdateCursor(*args)
            self.row = None
     
        def __iter__(self):
            return self
     
        def __enter__(self):
            return self
     
        def __exit__(self, exc_type, exc_val, exc_tb):
            if self.row: del self.row
            del self.cur
            return False
     
        def next(self):
            self.row = self.cur.next()
            return self.row
     
        def __getattr__(self, name):
            # on délègue les autres méthodes au curseur
            return getattr(self.cur, name)
     
    # ouvrir un UpdateCursor, reprenant les champs code_maille, effort_maille et rang, trié sur code_maille et sur effort_maille descendant
    with SafeUpdateCursor(...) as rows:
        maille_courante = None
        for row in rows:
            if maille_courante == row.code_maille:
                rank += 1
            else:
                rank = 1
            row.rang = rank
            rows.updateRow(row)
    Ce n'est pas simple je l'admets... La classe SafeUpdateCursor remplace la fonction UpdateCursor. Les méthodes __enter__ et __exit__ font de cette classe un gestionnaire de contexte qui peut être utilisé avec "with". Je ne tenterais pas d'expliquer plus en détail son fonctionnement, d'autant plus que je ne suis pas certain qu'il n'y ait pas d'erreur vu que je n'ai pas testé ce code (je n'ai pas arcgis). Une fois que tout est en place, tu peux remarquer que le code qui manipule le curseur est simplifié vu qu'il ne faut plus s'occuper explicitement ni des exceptions ni de libérer le curseur ou la ligne.

  20. #20
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    321
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 321
    Points : 109
    Points
    109
    Par défaut
    Je te remercie pour le temps que tu m'a accordé, d'une simple lecture je ne comprend pas tout (je debute ) mais je vais essayer de le décortiquer et d'y voir plus clair demain.

    merci

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Selectionner le deuxième plus grand nombre.
    Par pantoreille dans le forum Langage SQL
    Réponses: 2
    Dernier message: 29/07/2008, 14h58
  2. Réponses: 2
    Dernier message: 16/04/2007, 11h53
  3. Réponses: 52
    Dernier message: 13/03/2007, 15h07
  4. Plus grand nombre possible
    Par lia dans le forum C++
    Réponses: 2
    Dernier message: 30/08/2006, 11h22
  5. [Access] Trouver qui a le plus grand nombre de visites
    Par maxidoh dans le forum Langage SQL
    Réponses: 13
    Dernier message: 03/04/2006, 03h00

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