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 :

gestion de gros fichier


Sujet :

Python

  1. #1
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 13
    Points : 9
    Points
    9
    Par défaut gestion de gros fichier
    Bonjour,

    J'ai un script à réaliser et je ne sais pas par quel bout le prendre.
    J'ai d'un coté un fichier plat A de 600000 lignes et de l'autre un second B de 400000.
    Je dois récupérer dans A toutes les lignes qui matche avec les lignes de B.

    Ma grosse inquiétude sont les performances, je ne souhaite pas avoir 20H de traitement.
    De plus les lignes de B, ne sont qu'une partie des lignes de A. Une fois matché je souhaite extraire des données des lignes de A

    Après quelques recherche sur le Oueb, je me pose toujours la question :
    1/ que dois je utiliser pour parser mon fichier A (set ? )
    2/ pour faire matcher B sur les lignes de A dois je utiliser le module re
    3/ pour extraire les infos dois-je utiliser des liste ou écrire dans mon fichier résultat.

    Existe-t-il une méthode pour avoir des performances intéressante ? ( je ne suis pas développeur de métier )
    car si j'utilise une boucle for imbriqué pour parser les fichiers j'aurai des perfs merdique ( je pense )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #!/usr/bin/python
    import os, re
     
    with open('result.txt', 'a') as result:
     
        with open(B) as b:
            blines = set(b)
            print 'process ' + str(filename)
    	with open(A) as a:
                alines = set(a)
    	    for line in alines:
                    for lines in blines:     <-- je bloque
                        result.write(s)
    J'ai à la fois un souci de méthode et de gestion de gros fichier merci pour vos pistes éventuelles.
    PS; j'ai recherché sur le forum, mais je n'ai pas trouvé de sujet équivalent

  2. #2
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Salut,

    Je vois que tu as déjà effectué un peu de recherche. Bonne démarche.

    Alors, conformément à ce qui est écrit ICI, il y a 3 méthodes pour lire un fichier, certaines plus rapide que d'autres. Mais selon celle retenue, il faut également être sur que tu dispose d'assez de mémoire pour lire.

    Donc perso, dans un premier temps, voici ce que je te propose (ce n'est pas optimisé certes, mais faut pas trop abuser ):

    Tu lit en entier le fichier le plus gros qui ne doit pas depasser quelques dizaines de MO je suppose, avec readlines. Ensuite, tu lit le fichier B (le plus petit) ligne par ligne et tu utilise la fonction IN. un petit exemple d'algo

    fichier_A = Lecture fichier A

    fichier B = ouverture fichier B
    pour chaque ligne du fichier B:
    si ligne IN fichier_A alors:
    enregistrement de ligne dans un fichier


    Alors c'est pas optimisé, mais cela te donne un debut de réponse, et un compromis entre perf et consommation mémoire.

  3. #3
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 13
    Points : 9
    Points
    9
    Par défaut
    Merci, le fichier le plus gros fait 3Go, et le plus petit 400Mo, d'où mes inquiétudes sur les perfs. J'ai déjà fait de la lecture de fichier séquentiel, mais jamais sur des volumétries comme celle ci.

    Bon je vais finir le script et tester mais le readlines me laisse perplexe sur du 3Go. merci du conseil.
    bon j'ai du boulot Je reviens vers vous.

    autre chose, je dois vérifier la présence de B dans A et écrire la ligne de A dans le fichier résultat.....

  4. #4
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    ouah.

    J'avoue que je visais plus les 100MO max, d'ou ma proposition.

    Dans ce cas il faut inverser dans mon algo fichier a et fichier B.

    Ce sera un peu plus long mais en terme de ressources plus efficace. Après dans la mesure ou tu teste systématiquement l'existence dans le fichier, ce devrait quand même assez rapide (relativement à la quantité de donnée of course).

    Utilise les timestamp pour mesurer les perfs. J'attend ton retour. Fonction de cela, on verra pour optimiser encore plus.

    Ne perd pas de vu que lire ligne à ligne est plus long que lire un fichier en entier. Donc en en chargeant un en mémoire, tu optimises déjà énormément les perfs.

  5. #5
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 13
    Points : 9
    Points
    9
    Par défaut
    Ok merci

  6. #6
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 916
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 916
    Points : 7 304
    Points
    7 304
    Par défaut
    Pour faire de l'optimisation, il faut déjà tester ! Après on améliore les temps en ayant une analyse bien définie... Lorsque tout cela est un maximum optimisé, on vérifie que cela convienne et si ce n'est pas le cas, alors il faudra revoir le langage utilisé, soit en utilisant un interpréteur python plus efficace comme PyPy, soit en poussant le vice si insuffisant avec l'interfaçage entre python et un langage compilé. Si avec tout cela ce n'est encore pas suffisant (ce qui m'étonnerait), alors changer de langage entièrement.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 356
    Points : 36 884
    Points
    36 884
    Par défaut
    Salut,

    Citation Envoyé par vincenlnx Voir le message
    Merci, le fichier le plus gros fait 3Go, et le plus petit 400Mo, d'où mes inquiétudes sur les perfs. J'ai déjà fait de la lecture de fichier séquentiel, mais jamais sur des volumétries comme celle ci.
    Pourquoi ne pas découper le fichier en N fichiers plus petits?

    Citation Envoyé par vincenlnx
    De plus les lignes de B, ne sont qu'une partie des lignes de A. Une fois matché je souhaite extraire des données des lignes de A
    L'opération de sélection d'une ligne de A et les informations qu'on doit en extraire... Tant que cela ne sera pas plus clair avec un code qui se contente de traiter quelques lignes signficatives, pas la peine d'essayer plus grand, plus vite...

    - W

  8. #8
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 13
    Points : 9
    Points
    9
    Par défaut
    Bon,

    J'ai potassé mais je suis loin du résultat..... désolé de vous déranger.

    J'ai découpé mon fichier de 3Go en fichier de 20000 lignes (100Mo); je teste mon script sur 1 de ses fichiers.
    Le temps d'éxécution est énorme. Je me rends bien compte que cela vient de ma façon de faire. pour simplifier le traitement,j'extrais uniquement la ligne complète du fichier A. je referrai un traitement dès que j'aurai mon fichier de résultat.

    avant de parler d'optimisation je crois que j'ai un problème de méthode ..... je vous mets mon code même si j'ai un peu honte
    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
    #!/usr/bin/python
    import os, time,datetime
    ts=time.time()
     
    with open('result.txt', 'a') as result:
     
     
              for filename in ['xaa',]:
                   print '################' + '\n' + 'WORK ON  ==>' + str(filename)
     
                   with open('A','r') as a:
     
                        alines = a.readlines()
     
                        with open('B','r') as b:
                            for line in b:
                                  matching=[s for s in alines if line in s ]   #<== mon fichier B étant assez gros (50000 lignes ) ca prend des plombes, j\'en suis à plus de 3H de traitement
                                  if matching:
     
                                       print 'FIND IT'
                                       result.write(matching[0])
     
     
     
     
    end=time.time()
     
    start_time=datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
    end_time= datetime.datetime.fromtimestamp(end).strftime('%Y-%m-%d %H:%M:%S')
     
    print start_time
    print end_time
    J'ai testé sur plus un fichier B plus petit ca fonctionne mais la méthode n'est pas bonne. bref je sèche.

  9. #9
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 916
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 916
    Points : 7 304
    Points
    7 304
    Par défaut
    À quoi sert cette ligne, je ne comprend pas ce que tu veux faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for filename in['xaa',]:
    Ce n'est pas le code que je ne comprend pas, c'est ce que tu veux faire, je précise !

    Pour lire un fichier on peut faire simple et déjà efficace

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    with open('A.txt', 'r') as f:
        for line in f:
            # traitement de chaque ligne du fichier A
    avant de parler d'optimisation je crois que j'ai un problème de méthode
    Certes et va falloir pallier à cela, car les optimisations c'est bien plus complexe, tant dans sa recherche, que dans la pratique... On verra cela plus tard.

  10. #10
    Futur Membre du Club
    Inscrit en
    Janvier 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 13
    Points : 9
    Points
    9
    Par défaut
    Etant donné que j'ai splitté mon fichier de 3Go, il y a plein de fichier axa, xab, xac, j'ai viré le reste des fichiers sachant que je remplacerai après par un os.listdir quand le script fonctionnera correctement sur un fichier

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 356
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 356
    Points : 36 884
    Points
    36 884
    Par défaut
    Salut,

    Ca serait bien de voir un peu à quoi ressemble vos données: des exemples, pas l'ensemble ;-(

    En supposant que le test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                            for line in b:
                                  matching=[s for s in alines if line in s ]   #<== mon fichier B étant assez gros (50000 lignes ) ca prend des plombes, j\'en suis à plus de 3H de traitement
                                  if matching:
     
                                       print 'FIND IT'
                                       result.write(matching[0])
    soit juste.
    [ s for s in alines if line in s ] construit la liste de toutes les lignes de A qui contiennent la ligne courante de B.
    Or il en suffit d'une pour que çà matche puisque write(matching[0])
    Si on écrit çà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for s in alines:
         for line in b:
              if line in s:
                     result.write(s)
                     break
    on sort de la boucle sur B dès qu'on trouve un match.

    Plus généralement, pour traiter rapidement de gros volumes de données, il faut pouvoir faire travailler les comparaisons en parallèles sur des "morceaux".
    Vous avez découpé A, vous pouvez aussi découper B en B1, B2, B3,...
    Une ligne de A "matche" si elle est dans au moins un des Bn.

    Pour faire fonctionner ce genre d'idée, il faudra utiliser le module multiprocessing et distribuer le boulot entre plusieurs "process".
    Ce n'est pas si compliqué mais çà demande d'avoir acquis un savoir-faire qui n'a rien a voir avec la programmation Python.

    - W

Discussions similaires

  1. Réponses: 26
    Dernier message: 30/09/2014, 16h57
  2. gestion de gros fichiers en C++
    Par buzzkaido dans le forum C++
    Réponses: 6
    Dernier message: 07/08/2012, 12h16
  3. Gestion de gros fichiers
    Par bpy1401 dans le forum Android
    Réponses: 10
    Dernier message: 03/07/2012, 13h40
  4. Gestion des (gros) fichiers
    Par schneed dans le forum C++Builder
    Réponses: 1
    Dernier message: 23/02/2009, 20h05
  5. [Composants texte] Gestion de gros fichiers
    Par sozie9372 dans le forum Interfaces Graphiques en Java
    Réponses: 8
    Dernier message: 22/05/2006, 11h03

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