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 :

trier un fichier csv


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut trier un fichier csv
    Désolé d'ouvrir un énième fil sur les fichiers csv mais je ne parviens pas à mes fins.

    Voici le début de mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    with open('class1.csv',newline='') as mon_fichier:
        global liste2
        liste2 = list(csv.reader((mon_fichier),dialect='excel',delimiter='\t',lineterminator='\n'))
     
    print(liste2)
    Voici ce que j'obtiens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [['AAA,aaa,,NC'], ['BBB,bbb,165.45'], ['CCC,ccc,'], ['DDD,ddd,151.04'], ['EEE,eee,200.02']]
    Je souhaiterais trier les lignes par ordre décroissant en fonction de la dernière colonne (qui parfois n'est pas remplie ou contient une chaîne : à la limite, je peux la remplir avec des 0 si besoin).
    Le tableau csv contient environ 120 lignes et 29 colonnes (c'est donc par colonne[28] que je souhaite effectuer le tri) et je souhaiterais enregistrer le résultat trié dans un autre fichier csv (ou une autre feuille du classeur).

    J'ai essayé un peu de tout, notamment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import operator
    liste_triee = sorted(liste2, key=operator.itemgetter(2), reverse = True)
    print(liste_triee)
    Mon souci est au niveau des éléments car le code suivant fonctionne très bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import csv
    import operator
     
    with open('essai-tri.csv',newline='') as mon_fichier:
        global liste2
        liste2 = list(csv.reader((mon_fichier),dialect='excel',delimiter='\t',lineterminator='\n'))
     
    liste3=[]
    for i in range(1,len(liste2)):
        liste3.append(liste2[i])
    print(liste3)
     
    liste_triee = sorted(liste3, key=operator.itemgetter(4), reverse = True)
    print(liste_triee)
    et donne le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [['jhh', '1', '2', '3', 'NC'], ['jfk', '5', '7', '9', '5'], ['jhfh', '6', '4', '8', '3'], ['kiol', '7', '4', 'j', '2'], ['jui', '5', '4', '4', '8']]
    [['jhh', '1', '2', '3', 'NC'], ['jui', '5', '4', '4', '8'], ['jfk', '5', '7', '9', '5'], ['jhfh', '6', '4', '8', '3'], ['kiol', '7', '4', 'j', '2']]
    C'est donc uniquement le problème de la remise à plat des listes, je pense.
    Fatigué peut-être, je tourne en rond, sans être avare de "print(...)" !

  2. #2
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Je me réponds tout seul et j'arrête : vraiment fatigué...

    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
    fichier_classe = open("class1-trie.csv", "w")
    sortie = csv.writer(fichier_classe)
     
    with open('class1.csv',newline='') as mon_fichier:
        liste2 = list(csv.reader((mon_fichier),dialect='excel',delimiter='\t',lineterminator='\n'))
        liste_splitee=[]
        for ligne in liste2:
            ligne_splitee = ligne[0].split(',')
            liste_splitee.append(ligne_splitee)
     
     
    import operator
    liste_triee = sorted(liste_splitee, key=operator.itemgetter(28), reverse = True)
     
    for ligne in liste_triee:
        sortie.writerow(ligne)
     
    fichier_classe.close()
    Par contre, une étrangeté :

    Les 'NC' sont en premier (pas grave) mais ensuite, cela va de 99.99 à 0 puis de 300 à 100 !
    Une idée pour le "bug" (je sais que le bug, c'est moi, mais je ne vois pas) ?

  3. #3
    Membre chevronné
    Homme Profil pro
    Développeur banc de test
    Inscrit en
    Mai 2014
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur banc de test
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2014
    Messages : 199
    Par défaut
    Citation Envoyé par marco056 Voir le message
    Je me réponds tout seul et j'arrête : vraiment fatigué...
    Les 'NC' sont en premier (pas grave) mais ensuite, cela va de 99.99 à 0 puis de 300 à 100 !
    Une idée pour le "bug" (je sais que le bug, c'est moi, mais je ne vois pas) ?
    Bonjour,
    je n'ai pas le fichier d'entrée pour bien comprendre, mais ça ressemble au comportement attendu de la fonction sort.

    sorted(['A', 'B', 'C', 'a', 'b', 'c', '0', '1', '2', '10', '99.99', '100'])
    Retourne : ['0', '1', '10', '100', '2', '99.99', 'A', 'B', 'C', 'a', 'c', 'b']

    Le fait que toute la liste soit en string le tri ne prend pas en compte la valeur de l'élément entier ou flottant mais sa valeur de codage du caractère unicode (ascii/utf-8/...) du premier caractère jusqu'au dernier, '0' (b'\x30') sera placé avant avant '9' (b'\x39'), puis les lettres majuscules 'A' (b'\x41') et les lettres minuscules 'a' (b'\x61') en suivant.

    C'est typiquement le comportement que vous retrouvez en créant plusieurs fichiers avec le nom 1.txt, 2.txt jusqu'à 9.txt puis 10.txt. Sur des anciens systèmes/plateforme le tri affichera 1.txt puis 10.txt puis 2.txt, parce que le premier caractère du texte "10" passe avant '2'. C'est d'ailleurs pour cela qu'il fallait rajouter des 001.txt pour éviter ce mauvais comportement de tri des fichiers. Mais depuis sur les systèmes modernes il y a un tri dit « naturel » qui est plus pragmatique pour une utilisation humaine.

    Maintenant pour pouvoir le mettre en application, il existe peut-être une fonction de tri « naturel » de la sorte.
    Et dans le cas contraire il faut se farcir les conversions et le tri des valeurs pour les repasser en texte.


    Je viens de voir la fonction de sorting sorted(), on peut lui faire passer des valeurs int et float:

    sorted([0, 1, 2, 10, 99.99, 100])
    Retourne : [0, 1, 2, 10, 99.99, 100]

    Mais si on mélange int et string on se retrouve avec l'erreur suivante: TypeError: unorderable types: int() < str()
    Il faut donc séparer une liste de ce qui est convertissable en entier/flottant, puis une liste de texte uniquement.

  4. #4
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    Citation Envoyé par YCL-1 Voir le message
    Maintenant pour pouvoir le mettre en application, il existe peut-être une fonction de tri « naturel » de la sorte.
    Et dans le cas contraire il faut se farcir les conversions et le tri des valeurs pour les repasser en texte.
    on peut s'en sortir à moindre frais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> import re
    >>> vrac = ['A', '99.99', 'C', 'a', 'b', '0', '1', 'B', '2', '10', 'c', '100']
    >>> sorted(vrac, key=lambda x: [(lambda y: int(y) if y.isdigit() else y)(i) for i in re.split('([0-9]+)', x)])
    ['0', '1', '2', '10', '99.99', '100', 'A', 'B', 'C', 'a', 'b', 'c']

  5. #5
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Merci à vous mais sauf erreur de ma part, cela ne répond pas à mon besoin :
    J'obtiens une liste de listes (lignes) que je veux trier en fonction de la valeur du dernier élément de chaque ligne, ces valeurs variant de 0 à 300, par exemple.
    En espérant d'autres idées...

  6. #6
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    Citation Envoyé par marco056 Voir le message
    sauf erreur de ma part, cela ne répond pas à mon besoin
    c'est très possible, je me contentais de rebondir sur ce que disait YCL-1

    concernant ton besoin j'ai à peu près compris que tu cherches à trier des trucs et que ça donne après traitement des trucs triés que t'as mis plus haut mais qui ne se ressemblent pas (entre la 1ere et la 2e liste que tu donnes y'a rien de semblable) et qu'à priori ça ne te satisfait pas... on pourrait penser que c'est déjà pas mal mais en réalité c'est pas suffisant pour que je puisse t'aider de manière concrète, au minimum je pense que tu aurais pu mettre un fichier ou quelques lignes de test ainsi que l'output attendu ça m'aurait aidé à comprendre, sinon peut-être que d'autres auront mieux compris que moi et pourront te répondre

  7. #7
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Citation Envoyé par marco056 Voir le message
    J'obtiens une liste de listes (lignes) que je veux trier en fonction de la valeur du dernier élément de chaque ligne, ces valeurs variant de 0 à 300, par exemple.
    En espérant d'autres idées...
    Bonjour,

    J'utilise souvent les "listes de listes" issues de csv: je veux donc bien essayer, mais j'ai besoin d'infos complémentaires:

    - fournir un exemple type de listes "avant" et les mêmes listes "après" (comportant, bien sûr, les difficultés à vaincre).

    - dans le cas où les données à trier ne sont pas de même type: dire ce qu'il faut faire.

    - idem si l'une des données n'existe pas

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/04/2015, 10h07
  2. Trier fichier csv
    Par memento80 dans le forum Général Python
    Réponses: 7
    Dernier message: 31/10/2011, 11h56
  3. Trier le contenu d'un fichier .csv
    Par KiraX10A dans le forum C++
    Réponses: 9
    Dernier message: 18/09/2009, 16h37
  4. [CSV] Trier un fichier CSV
    Par arnaudperfect dans le forum Langage
    Réponses: 9
    Dernier message: 11/02/2008, 19h10
  5. [VMS] Trier un fichier type CSV
    Par gege2061 dans le forum Autres langages
    Réponses: 3
    Dernier message: 18/05/2007, 14h04

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