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 :

problème mémoire sur une liste avec du python


Sujet :

Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Mars 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur validation

    Informations forums :
    Inscription : Mars 2016
    Messages : 3
    Par défaut problème mémoire sur une liste avec du python
    Bonjour j'ai un problème : j'ai un fichier texte d'enregistrement de trames ARINC qui fait 600Mo de taille en voici une exemple:
    3:238:2147483817;4:318:67092608;1:447:2091276496;5:506:1610620119;3:638:2147483818;4:691:1611137153;1:802:2146916564;5:855:2147473624;
    Chaque data est séparée par un ; l encodage du fichier est comme ceci Numéro de ligne:TimstampataArinc; ect...
    je voudrais traiter se fichier (.txt) en python pour ne garder les ligne 1 et 2 garder uniquement (1:447:2091276496;1:802:214691656) pour cet exemple précis:
    J'ai commencé un bout de code en python pour filtrer la ligne 1:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    source = open("test.txt", "r").read()
    source = source.split(";")
    destination = open("Final.txt", "w")
     
     
    ArincNumber1 = "2:"
    for line in source:
        if ArincNumber1 in line:
            print (line)
    destination.write(line)
    le problème est que j'ai un souci sur l'écriture mais le plus grave est que cette méthode ne me permet de filtrer unqiquement sur la ligne 1 car je recherche en fait 1: sur toute la chaine et que qd j'y met le fichier de 600Mo Python mes sort une erreur comme quoi ma mémoire est insuffisante, PS j'Ai 8Go de RAM.
    Merci d'avance pour votre aide je ne connais pas du tout python

  2. #2
    Candidat au Club
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Mars 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur validation

    Informations forums :
    Inscription : Mars 2016
    Messages : 3
    Par défaut Problème mémoire
    alors j'ai un peu avancé concernant le traitement de mon fichier voici le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    fichier = open("A429_message.txt","r").read()
    data = fichier.split(";")
     
     
    for line in data:
    	#print(line[0:1])
    	#print(line)
    	if line[0:1] == "2" or line[0:1] == "1" :
    		print (line)
    ça marche nikel pour un fichier de 100Mo mais pour un fichier de 600Mo voici le code d'erreur de la console

    C:\EAGLE\A429_EAGLE>python OpenFile.py
    Traceback (most recent call last):
    File "OpenFile.py", line 2, in <module>
    fichier = open("A429_message1.txt","r").read()
    File "C:\Users\dsiret\AppData\Local\Programs\Python\Python35-32\lib\encodings\
    cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
    MemoryError

  3. #3
    Membre éclairé Avatar de nekcorp
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2006
    Messages : 592
    Par défaut
    Citation Envoyé par denis13008 Voir le message
    alors j'ai un peu avancé concernant le traitement de mon fichier voici le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    fichier = open("A429_message.txt","r").read()
    data = fichier.split(";")
     
     
    for line in data:
    	#print(line[0:1])
    	#print(line)
    	if line[0:1] == "2" or line[0:1] == "1" :
    		print (line)
    ça marche nikel pour un fichier de 100Mo mais pour un fichier de 600Mo voici le code d'erreur de la console

    C:\EAGLE\A429_EAGLE>python OpenFile.py
    Traceback (most recent call last):
    File "OpenFile.py", line 2, in <module>
    fichier = open("A429_message1.txt","r").read()
    File "C:\Users\dsiret\AppData\Local\Programs\Python\Python35-32\lib\encodings\
    cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
    MemoryError
    Salut,

    à quoi ressemble ton fichier texte ?

  4. #4
    Membre éclairé Avatar de nekcorp
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2006
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2006
    Messages : 592
    Par défaut
    J'ai essayé de reproduire ton soucis

    Alors mon script va créer un fichier en écrivant "salut" sur 100 millions de lignes ce qui équivaut à un fichier de 700Mo.

    Lorsque je veux ouvrir le fichier et faire un print des lignes commençant pas "s" j'obtient ce message d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Traceback (most recent call last):
      File "C:\Users\test\Desktop\test_script.py", line 10, in <module>
        for l in f_input :
    IOError: File not open for reading
    Et voici le code qui permet de faire ça :
    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
     
    f_input = open("fichier.txt", "w")
    n=100000000
    for i in range(1, n, 1):
        f_input.write("salut \n")
    f_input.close()
     
    f_input = open("fichier.txt", "r")
    f_output = open("fichier_output.txt", "w")
     
    for l in f_input :
        if l[:1] == "s" :
            print l
     
    f_output.close()
    f_input.close()
    Dans mon cas il n'arrive même pas à l'ouvrir.

    tu peux tronquer ton fichier en fichier plus petits (6 fichiers de 100Mo).

    après pour ton message d'erreur je ne suis pas assez avancé en python pour le comprendre.

  5. #5
    Candidat au Club
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Mars 2016
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur validation

    Informations forums :
    Inscription : Mars 2016
    Messages : 3
    Par défaut
    salut mon fichier à une seule ligne de cette forme:
    3:238:2147483817;4:318:67092608;1:447:2091276496;5:506:1610620119;3:638:2147483818;4:691:1611137153;1:802:2146916564;5:855:2147473624;3:957:171;4:1000:642;1:1162:2147141845;5:1216:2147475674;3:1297:3762331052;4:1341:131;1:1511:3758097593;5:1564:2147387609;3:1679:2707884461;4:1741:1270880389;1:1907:1954431163;5:1961:2134040795;3:2043:174;4:2087:1628135781;1:2232:3791651004;5:2286:2147464437;3:2407:2147483754;4:2452:3783957184;1:2600:3758129338;5:2654:2091276496;3:2744:2147483756;4:2788:3782063809;1:2952:3764388029;5:3006:536871850;3:3096:8388791;4:3140:1566036418;

    Chaque données est séparée par ;

  6. #6
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 988
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 988
    Par défaut
    Le truc c'est que quand on manipule des gros fichiers, on ne stocke pas tout en mémoire avec un open(....).read(), mais on lit le contenu du fichier au fur et à mesure. Alors c'est plutôt simple quand on peut lire le fichier ligne par ligne avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    with open('toto') as f:
        for line in f:
            print(line)
    Mais dans ton cas la difficulté est que tout est sur une ligne, donc il faut ruser en le lisant morceau par morceau et en faisant le découpage des enregistrements dans un generator. Voici un exemple qui se contente d'afficher tous les enregistrements:
    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
    def arinc_records(fh, bucket_size = 1024):
        remainder = ''
        while True:
            bucket = fh.read(bucket_size)
            if not bucket:
                break
            records = bucket.split(';')
            records[0] = remainder + records[0]
            remainder = records.pop()
            for record in records:
                yield record
        if remainder:
            yield remainder
     
    with open('arinc.txt') as f_input:
        for record in arinc_records(f_input):
            print(record)

    L'idée est de lire une portion de taille déterminée du fichier (ce que j'ai appelé bucket, un seau), de splitter cette portion aux points-virgules et en stockant le dernier morceau potentiellement incomplet (remainder, le restant) pour pouvoir le recoller à la portion suivante.

    Dans ton cas la meilleur solution serait de sélectionner les enregistrements qui t'intéressent directement dans le generator pour ne renvoyer que ceux-ci, et de les écrire (au fur et à mesure, bien entendu) dans le fichier destination que tu peux ouvrir dans la foulé en même temps que le fichier source:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    with open('source') as f_input, open('destination', 'w') as f_output:



    Il est aussi possible d'utiliser les modules mmap et re:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    import mmap
    import re
     
    with open ('arinc.txt', 'rb') as f_input, open ('destination.txt', 'wb') as f_output:
        mm = mmap.mmap(f_input.fileno(), 0, access = mmap.ACCESS_READ)
        for record in re.finditer(rb'\b[12]:[^;]+', mm):
            f_output.write(record.group(0))
        mm.close()
    Ce qui évite les créations de listes et tout encodage en utf-8.

  7. #7
    Membre émérite
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Par défaut
    Bonjour,
    Je reviens sur cette discussion pour une petite question:
    Pourquoi ne pas utiliser le module "csv" de Python3? Il me semble que le "reader" est un itérateur, non?
    Il suffit d'associer le "reader" à un "delimiter=";""?

    Un exemple est donné dans la documentation.

    Ou, peut-être le "reader" passe-t-il par une lecture préalable par lignes?

    Clodion

  8. #8
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 988
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 988
    Par défaut
    Ce n'est pas possible d'utiliser le module csv dans ce cas car il s'agit d'une ligne unique.
    La méthode csv.reader renvoie bien un itérateur, mais cette itérateur renvoie pour chaque enregistrement un liste avec la totalité des champs de l'enregistrement. Dans ce cas précis, l'itérateur ne renverra qu'une seule liste avec des centaines de milliers d'éléments, ce qui fait que la totalité du fichier sera présente en mémoire sous forme d'une liste géante.

    L'idéal serait de pouvoir imposer un séparateur d'enregistrements autre qu'une nouvelle ligne, ainsi on pourrait utiliser ; et pour le séparateur de champs on utiliserait :. L'itérateur renverrait alors ['3','238','2147483817'], puis ['4','318','67092608'], puis ['1','447','2091276496'], etc. ce qui simplifierait considérablement la tâche et permettrait donc de lire et de traiter le contenu du fichier au fur et à mesure.

    Mais ce n'est malheureusement pas possible à cause d'une fichue limitation (la documentation signale qu'elle pourrait être levée un jour) qui fait que le reader prend obligatoirement la nouvelle ligne comme séparateur d'enregistrement et ignore Dialect.lineterminator.

  9. #9
    Membre émérite
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Par défaut
    Bonsoir,
    @CosmoKnacki
    Oui, c'est ce que j'imaginais…
    Merci pour ces précisions.

    Clodion

Discussions similaires

  1. [SP-2010] Problème hyperlien sur une liste
    Par ry4n_spirit dans le forum SharePoint
    Réponses: 3
    Dernier message: 06/02/2014, 20h30
  2. Problèmes entités sur une liste déroulante liée
    Par Trezegoals dans le forum Doctrine2
    Réponses: 0
    Dernier message: 24/08/2012, 10h13
  3. Réponses: 0
    Dernier message: 27/04/2012, 18h16
  4. Réponses: 8
    Dernier message: 30/09/2006, 05h18
  5. Réponses: 4
    Dernier message: 16/06/2005, 15h37

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