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 :

Créer deux listes à partir d'un fichier à plusieurs colonnes


Sujet :

Python

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    125
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Août 2008
    Messages : 125
    Points : 55
    Points
    55
    Par défaut Créer deux listes à partir d'un fichier à plusieurs colonnes
    Bonjour,

    j'ai un fichier avec 5 colonnes par exemple, dont la première ligne est un entête.
    je voudrais extraire de ce fichier la colonne 1 par exemple (sans l'entête si possible) et la colonne 4.
    J'ai essayé readlines() cela me crée une seule liste avec l'ensemble du fichier, donc inbitable,
    j'ai essayé également ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Freq = {}
    ModS21 = {}
    tb = []
    for ligne in open(fileS21,'r'):
        tb.append(ligne.split('\t'))
        Freq[ligne] = tb[-1][0]
        ModS21[ligne] = tb[-1][3]
    print Freq[ligne]
    print ModS21 [ligne]
    Mais là je rencontre deux problèmes : je n'arrive pas à en faire une liste, et si j'y arrive, cela me garde en mémoire la dernière ligne de mes deux colonnes...

    avez-vous une idée pour que j'arrive à faire ce que je veux, sans passer par une modification manuelle de mon fichier texte

    je vous remercie par avance

    Patricia

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Ton algorithme est presque bon, mais déjà tes dictionnaires sont indexés par le contenu de la ligne, ce qui n'est vraiment pas pratique.
    Tu peux utiliser des listes, et leur ajouter (liste.append(element)) les éléments à chaque itération. Tu auras ainsi deux listes indexées par le numéro de ligne (attention, la première ligne a pour numéro 0).
    Dernière erreur, tu affiches les dernières valeurs insérées dans tes dicos, mais Python a quand même gardé le reste en mémoire.
    Enfin, je ne vois pas trop l'intérêt de garder une troisième liste.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Freq = []
    ModS21 = []
    for ligne in open(fileS21,'r'):
        tb = ligne.split('\t')
        Freq.append(tb[0])
        ModS21.append(tb[3])
    print Freq
    print ModS21
    Ce code t'affichera les 2 listes que tu veux.

    Au cas où :
    FAQ sur les listes
    FAQ sur les dicos

  3. #3
    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 Salut.Je ferais comme suit.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    f = open(fileS21,'r')
    lif = f.read().partition('\n')[2].replace('\n','\t').split('\t')
    f.close()
    Freq = [ lif[5*k] for k in range(len(lif)) ]
    ModS21 = [ lif[5*k+3] for k in range(len(lif)) ]
    Sous réserve que j'aie bien compris la structure du fichier:

    f.read() produit un string
    partition('\n')[2] élimine l'en-tête (à condition qu'il soit sur la première ligne, avant le premier \n)
    replace('\n','\t').split('\t') crée une longue liste dans laquelle toutes les valeurs de fileS21 sont à la queue leuleu, les valeurs de la première colonne étant aux positions 0,5,10,15,20,25...., les valeurs de la colonne 4 étant aux positions 3,8,13,28,23,28....



    En évitant d'utiliser append() et une boucle for, ce qui, me semble-t-il, doit être plus lent que des list comprehensions, ça doit aller plus vite, je pense. Il faudrait tester.

  4. #4
    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 J'ai amélioré mon petit programme.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        f = open('fich5col','r')
        lif = f.read().replace('\n','\t').split('\t')
        f.close()
        Freq = [ lif[k] for k in range(0,len(lif),5) ]
        ModS21 = [ lif[k] for k in range(3,len(lif),5) ]

    - J'ai éliminé partition('\n')[2] que j'avais mis en pensant que la première ligne pouvait ne pas avoir des '\t'.
    Mais en supposant que la première ligne comporte 5 en-têtes séparés par des \t, un en-tête par colonne, ça simplifie de l'enlever.

    - D'autre part, pas besoin d'indices calculés, il suffit d'utiliser les possibilités d'écriture de range(...).


    - D'autre part, je me suis astreint à vérifier mon idée, pour être un peu sérieux.
    J'ai utilisé Timer du module timeit pour comparer les temps d'exécution de 3 méthodes.
    Le recours au module timeit est plus précis pour mesurer des temps d'exécution que le recours à clock().


    Timer(expression1, expression2) crée un truc à partir duquel peuvent être mesurés des temps d'exécution de expression1. L'expression additionnelle donne des précisions pour que ça puisse tourner.

    Avec Timer(expr1,expr2).timeit(7) ,
    le temps d'exécution de 7 fois l'expression expr1 est mesuré ( 1 million de fois par défaut en l'absence d'argument dans timeit() ).

    Avec Timer(expr1,expr2).repeat(12,7),
    12 temps d'exécution de 7 itérations chacun de l'expression expr1 sont mesurés et renvoyés dans une liste.
    Une fois que la liste est obtenue, on peut en extraire le minimum et la moyenne.


    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
    from timeit import Timer
     
    def fonction1():
     
        f = open('fich5col','r')
        lif = f.read().replace('\n','\t').split('\t')
        f.close()
        Freq = [ lif[k] for k in range(0,len(lif),5) ]
        ModS21 = [ lif[k] for k in range(3,len(lif),5) ]
     
    def fonction2():
        f = open('fich5col','r')
        lif = f.read().replace('\t','\n').splitlines()
        f.close()
        Freq = [ lif[k] for k in range(0,len(lif),5) ]
        ModS21 = [ lif[k] for k in range(3,len(lif),5) ]
     
     
    def fonction3():
        Freq = []
        ModS21 = []
        f = open('fich5col','r')
        for ligne in f:
            tb = ligne.split('\t')
            Freq.append(tb[0])
            ModS21.append(tb[3])
        f.close()
     
     
     
    ITERATIONS = 10
    REPETITIONS = 25
     
     
    print "Résultats sur",REPETITIONS,"répétitions de",ITERATIONS,"itérations\n\n"
     
     
     
    titi = Timer('fonction1()', 'from __main__ import fonction1')
    res1 = titi.repeat(REPETITIONS,ITERATIONS)
    sum = 0
    for y in res1:
        sum = sum + y
    print "\n\n\tfonction1:  lif = f.read().replace('\\n','\\t').split('\\t')\n"
    print 'temps minimal =',min(res1)," secondes"
    print "  temps moyen =",sum/REPETITIONS," secondes"
     
     
     
    titi = Timer('fonction2()', 'from __main__ import fonction2')
    res2 = titi.repeat(REPETITIONS,ITERATIONS)
    sum = 0
    for y in res2:
        sum = sum + y
    print "\n\n\tfonction2:  lif = f.read().replace('\\t','\\n').splitlines()\n"
    print 'temps minimal =',min(res2)," secondes"
    print "  temps moyen =",sum/REPETITIONS," secondes"
     
     
     
    titi = Timer('fonction3()', 'from __main__ import fonction3')
    res3 = titi.repeat(REPETITIONS,ITERATIONS)
    sum = 0
    for y in res3:
        sum = sum + y
    print "\n\n\tfonction3:  boucle for et append()\n"
    print 'temps minimal =',min(res3)," secondes"
    print "  temps moyen =",sum/REPETITIONS," secondes"

    Je n'ai pas lésiné: j'ai appliqué les méthodes à la lecture d'un fichier 'fich5col' de 2 MB. dont le contenu était du genre:

    colonne1 colonne2 colonne3 colonn4 colonne5
    34567897 98687633666 879 998 0886664
    1233 765765 664553 77766666666 2234
    34567897 98687633666 879 998 0886664
    65 543 98 765342 767676
    987987 65656 566566 098 8988
    1 2 3 4 5
    879 8098 65765 88888098009808 67587665
    126777575765765 86868687687 8768686 6866 6876876876876
    65 543 98 765342 767676
    987987 65656 566566 098 8988
    1 2 3 4 5
    1233 765765 664553 77766666666 2234
    126777575765765 86868687687 8768686 6866 6876876876876
    etc etc....
    Les temps sortis se rapportent à 10 fois la lecture de ce fichier.
    Selon la méthode employée, une lecture prend donc de 0,55 à 0,75 seconde.



    Résultat:

    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
    Résultats sur 25 répétitions de 10 itérations
     
    	fonction1:  lif = f.read().replace('\n','\t').split('\t')
     
    temps minimal = 5.68055493086  secondes
      temps moyen = 5.84316176497  secondes
     
    	fonction2:  lif = f.read().replace('\t','\n').splitlines()
     
    temps minimal = 5.94775257749  secondes
      temps moyen = 6.08086265713  secondes
     
    	fonction3:  boucle for et append()
     
    temps minimal = 7.29581050106  secondes
      temps moyen = 7.44640279142  secondes



    Comme je le pensais, l'emploi d'une boucle for et de append() est 28 % plus longue que l'emploi de list comprehensions. La différence n'est pas énorme mais confirme la préférence à accorder aux list comprehensions quand c'est possible. De plus, ma proposition exploite la concision de Python qui m'ébahit à chaque fois.

    fonction2() est légèrement plus longue que fonction1() parce que replace('\t','\n') a plus d'occasions de travailler dans la chaine que replace('\n','\t').

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Août 2008
    Messages
    125
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations professionnelles :
    Secteur : Service public

    Informations forums :
    Inscription : Août 2008
    Messages : 125
    Points : 55
    Points
    55
    Par défaut merci pour votre aide
    J'ai eu ma réponse en combinant vos deux propositions.

    Merci !

    PAtricia

Discussions similaires

  1. [Toutes versions] créer une liste à partir de fichier
    Par Rico75 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 17/03/2010, 20h01
  2. [FPDF] Créer PDF dynamiquement à partir d'un fichier PHP
    Par Banks dans le forum Bibliothèques et frameworks
    Réponses: 5
    Dernier message: 27/09/2007, 23h58
  3. créer un excel à partir d'un fichier texte
    Par titomiss dans le forum Modules
    Réponses: 1
    Dernier message: 21/09/2007, 10h55
  4. Remplir une liste à partir d'un fichier texte
    Par leroidje dans le forum Langage
    Réponses: 1
    Dernier message: 01/07/2007, 09h41
  5. Créer un parseur à partir d'un fichier MATLAB
    Par Sensib dans le forum MATLAB
    Réponses: 4
    Dernier message: 04/10/2006, 15h41

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