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 :

Lenteur dans le parcours d'un txt de 3 millions de lignes


Sujet :

Python

  1. #1
    Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Juillet 2013
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2013
    Messages : 55
    Points : 65
    Points
    65
    Par défaut Lenteur dans le parcours d'un txt de 3 millions de lignes
    Bonjour à tous,

    J'ai besoin d'un petit coup de main pour améliorer mon programme python.
    J'ai un fichier txt qui contient environ 3 millions de lignes. Je voudrais utiliser ce fichier pour alimenter 9 dataframes.
    En effet chaque ligne du fichier txt contient des renseignements sur les variables de mes différents dataframes (je connais la position et la longueur de chaque variable...).

    Mon programme est celui là :
    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
     
    index = 0
    with open('leFichier.txt', 'r') as input_file :
     
          for line in input_file :
     
               if line[x:y] in listeNomsDF :
     
                  dfRow = []
                  for i in range( 0, len(colNames[line[x:y]]) ) :
                       colValue = line[debut:fin]
                       dfRow.append(colValue.strip())
     
               index = df[line[x:y]].shape[0] + 1
               df[line[x:y]].loc[index] = dfRow
    Le programme fait le job quand je le teste sur un échantillon de quelques lignes mais quand je passe à la totalité du fichier txt le programme prend des plombs à s'exécuter (plus de 2h...) et je finis par l'arrêter.
    Avez des idées pour m'aider à l'optimiser et accélérer l'exécution ?

    Merci par avance

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

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

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    sans être un expert, la seule opti que je verrai en l'état serait de stocker en début de traitement bidule = line[x:y] pour éviter d'avoir à le re-calculer à chaque fois, mais je doute que ça fasse réellement une grosse différence, idem ta ligne 11, on peut raisonnablement penser que colValue ne change pas d'une itération à l'autre

    tout dépend dans quoi on écrit (des fichiers, une db un peu lente etc.) et quoiqu'il en soit 3M de lignes ça commence à faire, au delà il va falloir profiler le code, éventuellement le paralléliser voire ajouter des ressources (machines, disques etc.), c'est plus probablement le stockage/le trajet qui pose souci que la complexité des opérations

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    my_index = 0
    with open('leFichier.txt', 'r') as input_file :
       for line in input_file :
          slice = line[x:y]
          if slice in listeNomsDF :
             dfRow = []
             colValue = line[debut:fin].strip()
             for i in range(len(colNames[slice])) :
                dfRow.append(colValue)
          my_index = df[slice].shape[0] + 1
          df[slice].loc[my_index] = dfRow

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur banc de test
    Inscrit en
    Mai 2014
    Messages
    199
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    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
    Points : 482
    Points
    482
    Par défaut
    Ça va dépendre beaucoup du contenu/format de vos données.

    Mais si la majeure partie de vos données sont des nombres stockés en caractères (encodés en ASCII ou autre) ou mieux en binaire, alors il y a grandement moyen d'améliorer la vitesse de chargement, le temps de parsing/formatage de vos données, et de diminuer fortement la mémoire de chaque élément stocké en RAM.

    Si vos données sont des nombres vous pouvez utiliser le module NumPy qui est assez efficace pour gérer une qualité importante de nombres et surtout pour y appliquer des opérations dessus.

    Par analogie on peut raisonnablement comparer NumPy à Matlab ou Scilab.

    Juste en remarque, il existe plusieurs moyens de charger des données avec Numpy, selon la source et les ressources de votre machine, un panel présenté ici : http://stackoverflow.com/a/8964779
    np.loadtxt, np.genfromtxt ou créer un itérateur avec np.fromiter pour diminuer l'effet du chargement avant parsing, bien pratique quand vos données pèses plusieurs Go.

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    En fait, 3 millions de lignes, ce n'est pas beaucoup, et ça se lit très rapidement: ce n'est pas ça qui freine.

    Je viens de faire un petit essai. Je fabrique un fichier texte de 3 millions de lignes au hasard entre 0 et 79 caractères alphabétique. Cette fabrication m'a demandé moins de 3 minutes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    from random import randint
    import time
     
    def creafic(fichier, nblignes):
        alpha = "abcdefghijklmnopqrstuvwxyz "
        with open(fichier, 'w', encoding="latin1") as fd:
            for i in range(0, nblignes):        
                lg = randint(1,78) # longueur de la ligne
                ligne = "".join([alpha[randint(0,26)] for i in range(0,lg)])
                fd.write(ligne + '\n')
    t = time.clock()
    creafic("fichier.txt", 3000000)
    t = time.clock()-t
    print(t)
    Le fichier construit "fichier.txt" a pour taille 115Mo, soit environ 40 caractères par ligne, ce qui est logique.

    Ensuite, on lit toutes les lignes du fichier:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def litfic(fichier, taillebuf=-1):
        with open(fichier, 'r', buffering=taillebuf, encoding="latin1") as fs:
            i = 0
            for ligne in fs:
                i += 1
                x = ligne.rstrip()
            # affiche la dernière ligne pour vérifier qu'on les a bien lu toutes
            print(i, "=>", x)
    Et la lecture demande... moins de 2 secondes.

    Conclusion: c'est sur l'algorithme de traitement des lignes qu'il faut travailler! Dans l'esprit de ce que propose BufferBob.

    Mais il est difficile d'aller plus loin sans bien connaître la nature de ces traitements. Par exemple, la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if line[x:y] in listeNomsDF :
    suggère qu'il y a une liste "listeNomsDF" dont on ne connait pas la taille. Or, la condition va nécessiter pour chaque ligne de tester la plupart des valeurs de cette liste. Si cette liste est longue, on peut accélérer le test en transformant cette liste en dictionnaire.

    Etc...
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

Discussions similaires

  1. [CRXI] Probleme lenteur dans l'editeur ...
    Par c_moi_c_moi dans le forum SAP Crystal Reports
    Réponses: 5
    Dernier message: 06/07/2007, 11h56
  2. Réponses: 4
    Dernier message: 22/11/2006, 17h48
  3. [disque dur]Lenteur dans le disque
    Par Kurdran dans le forum Composants
    Réponses: 5
    Dernier message: 03/10/2006, 10h20
  4. lenteur dans l'insertion de donnees en 10Gr2
    Par JUSTIN Loïc dans le forum SQL
    Réponses: 55
    Dernier message: 22/09/2006, 20h55
  5. lenteur dans l'execution!
    Par JauB dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 06/06/2006, 11h39

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