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 :

optimisation fichier long


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Par défaut optimisation fichier long
    Bonjour, avant d'expliquer mon pb,
    je vous montre un exemple :
    j'ai un fichier
    <motA>1##2##3##4</motA>
    <motB>1##4##8</motB>
    <motC>5##8##10</motC>
    <motD>35##32##10</motD>
    <motE>52##81##102</motE>
    je dois comparer
    <motA> avec <motB>
    <motA> avec <motC>
    <motA> avec <motD>
    <motB> avec <motC>
    <motB> avec <motD>
    <motC> avec <motD>

    donc
    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
     
    f = openFile("mat1.log")
    lp = f.readlines()
    fg = openFile("mat1.log")
    d = fg.readlines()
    n=1
    chaine=[]
    countList={}
    for i in lp:
    	listeA = re.findall('<.*?>(.*?)</.*?>',i)
    	element = re.findall('<(.*?)>',i)
    	chaine.append("<" + element[0] + ">")
    	for j in d[n:]:
    		listeB = re.findall('<.*?>(.*?)</.*?>',j) #recupère la liste entre les balises
    		elementj = re.findall('<(.*?)>',j)#récupère l'élement de la balise
    		diceValue = dice(creerListe(listeA[0]),creerListe(listeB[0])) 
    #creerListe qui transforme la chaine 5##8##10 en une liste de 3 élements
    		if diceValue > 0.0 and diceValue < 1.0:
                            countList[elementj[0]]=diceValue
    	lcountlist = countList.items()
    	lcountlist.sort(key=operator.itemgetter(1),reverse=True)
    	lcountlist = lcountlist[:m]
    	for alllist in range(len(lcountlist)):
    		if alllist != len(lcountlist) - 1:
    			chaine.append(lcountlist[alllist][0]+"##")
    			else:
    				chaine.append(lcountlist[alllist][0])
    		chaine.append("</" + element[0] + ">\n")
    		n+=1
    		cp+=1
    	f1 = open("matricecooccurrenceTest.log","w")
    	f1.writelines(chaine)
    	f1.writelines(chaineAutre)
    	f.close()
    	f1.close()
    	fg.close()
    le code est trop long je trouve.
    c'est un très gros fichier,je sais pas si mon algo est optimale, mais là, j'ai lancé le fichier pendant 16h
    et il n'a meme pas traité 50000 mots.
    il y a au total 150000 mots (lignes) à traiter.

  2. #2
    Membre émérite

    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
    Par défaut
    Déjà, compile tes regex
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    r1 = re.compile('<.*?>(.*?)</.*?>')
    r2 = re.compile('<.*?>(.*?)</.*?>')
    (ensuite, tu utilises par exemple listeA = r1.findall(i))
    Ensuite, je doute que ce soit raisonnable pour un gros fichier de le lire avec readlines(), qui plus est, deux fois !
    Tu peux itérer sur les lignes du fichier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for ligne in fichier:
        traiter(ligne)
    Ou bien utiliser readline() qui renvoie une ligne à la fois et passe automatiquement à la suivante
    De même pour l'écriture, mieux vaut écrire au fur et à mesure.
    Ensuite, tu effaces ton fichier de sortie à chaque itération, ce qui n'est pas très judicieux je pense.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Par défaut
    non j'efface les fichiers à la fin,
    c'est juste le copier /coller sur l'interface qui est mal passé !!

    merci, je vais essayer tes recommandations

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Par défaut
    en fait, dans mon cas lire le fichier ligne par ligne n'est pas très judicieux.
    car étant donné que je dois comparer chaque ligne entre elle:

    comme
    ligne1 avec ligne2
    ligne1 avec ligne3
    ligne1 avec ligne4
    ensuite
    ligne2 avec ligne3
    ligne2 avec ligne4

    si je lis ligne par ligne.
    je vais comparer
    ligne1 avec ligne1
    ligne1 avec ligne2
    etc..
    ligne2 avec ligne1
    ligne2 avec ligne2
    etC...
    la complexité est O(n²)
    et là c lourd.
    j'ai voulu les mettre dans readlines() pour avoir une liste
    et ensuite avec liste[n:]
    ça m'évite de comparer les valeurs précédentes.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Par défaut
    j'ai une fonction creerListe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def creerListe(list):
    	l = list.split("##")
    	return l
    à chaque r1.findall(i)
    il me retourne la chaine qui se trouve entre les balises <i>
    par ex : 1#2#3#4
    et là, je souhaite mettre chaque élément dans une liste = ["1","2","3","4"]
    à ton avis, le split c'est une bonne solution ou ça ralentit aussi, car il arrive parfois qu'il y ait une chaine avec 400 mots séparé des #. (y en a meme plusieurs cas similaires)

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Par défaut
    en fait split ou pas split, c pareil,
    j'ai enlevé tout le code à l'intérieur de la seconde boucle.
    ça rame tjs autant.
    je crois
    que c les boucles imbriquées, ça prend énormément de temps.

    là je vois pas trop comment faire !!

  7. #7
    Membre émérite

    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
    Par défaut
    (Petite note, les 2 méthodes sont en O(n²) en nombre de lignes lues)
    Ce que je te conseille, c'est de traiter d'abord une fois le fichier (tous les découpages à faire) comme ça tu n'auras plus qu'une liste de listes à parcourir après.

    Pour le découpage, tu peux te limiter à une regex :
    Si ligne contient la ligne à traiter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    rx = re.compile('<(.*?)>(.*?)</.*?>')
    #dans ta boucle de traitement:
    element = rx.findall(ligne) #liste (nom, valeur)

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    358
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 358
    Par défaut
    si j'ai bien compris, je dois parcourir le fichier une fois pour récupérer dans une liste toutes les lignes
    par ex:
    liste = ["<a>1#2#3</a>","<b>2#4#1</b>"]

    mais après je ne vois pas la solution, car je vais tout de même devoir faire une double imbrication pour comparer chaque mots entre eux.

    à moins que parcourir une liste, ça prend moins de temps ?

  9. #9
    Membre Expert
    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
    Par défaut brrrrrr
    À vue de nez, c'est sûr et certain que ça ne peut que ramer. Python et les ordinateurs sont puissants, mais il ne faut quand même pas exagérer dans ce qu'on leur demande. Je peux me tromper mais il me semble que ton code est bourré de mauvaises pratiques, et plus grave, que c'est l'algorithme lui-même qui me semble mauvais. Il va falloir te faire à l'idée que ton code est à reprendre de fond en comble. À mon humble avis.

    Avant tous les autres problèmes, il y a que tu ne donnes pas assez de renseignements sur ce projet de programme.

    Quelle est la structure excate du fichier "mat1.log" à examiner ? Le peu que je comprends du code ne colle pas avec ce que tu en dis.

    Qu'est ce que le programme est censé faire d'un point de vue général ?

    Je vois
    if diceValue > 0.0 and diceValue < 1.0
    dice (Qu'est ce que c'est ce truc de "dice" ?)
    sort.
    Question importante: un tri de quelque chose doit il être réalisé à un moment ou un autre lors de l'exécution ? Ce tri a-t-il une importance centrale dans le programme ? Si oui, il faut penser l'algorithme autour de cette nécessité.


    Un autre point autour duquel concevoir l'algorithme, c'est la grande taille de ton fichier de départ. Ça exclut d'en faire une lecture complète d'un coup avec readlines() car readlines() crée une liste, c'est à dire un objet-liste en mémoire vive de l'ordinateur. Si la liste est énorme et la RAM un peu insuffisante, l'encombrement de la RAM diminue la vitesse d'exécution.
    Quelle est la taille de ta RAM et pendant qu'on y est la fréquence de ton CPU (processeur) ?

    Faire f.read() au lieu de f.readlines() ne résoudra rien. f.readlines() crée une liste et f.read() crée une chaine de caractères, mais les deux contiendront approximativement le même nombre de caractères.

    Il va falloir t'orienter sur une lecture et un traitement par à coups du fichier, et pour faciliter le tritement il faudra vraisemblablement faire appel aux fonctions seek() et tell().


    ---

    Le mieux pour comprendre exactement la structure du fichier serait que tu exécute dessus le petit bout de programme suivant, et ensuite, si tu veux bien nous dire ce que tu veux que le programme fasse sur le fichier, on pourra peut être avancer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    f = openFile("mat1.log")
    lp = f.readlines(1500)
    for ln in lp:
        print ln
    f.close()

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

Discussions similaires

  1. importer fichier long
    Par mizou00 dans le forum Macros et VBA Excel
    Réponses: 15
    Dernier message: 13/08/2010, 08h15
  2. Impossible de transferer des fichiers long
    Par feldene dans le forum Langage
    Réponses: 4
    Dernier message: 24/03/2010, 17h38
  3. Copier les fichiers long Win98/ME
    Par compdev dans le forum Windows 2000/Me/98/95
    Réponses: 1
    Dernier message: 11/09/2009, 21h50
  4. nom de fichier long
    Par karim_usthb dans le forum Scripts/Batch
    Réponses: 0
    Dernier message: 02/06/2008, 11h50
  5. [Win XP] Optimisation (fichier de "swap" et RAM)
    Par BiM dans le forum Windows XP
    Réponses: 11
    Dernier message: 05/04/2006, 12h13

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