2011-08-02 2 views
0

J'ai utilisé .readline() pour analyser le fichier ligne par ligne, car j'ai besoin de pour trouver la position de départ pour extraire les données dans une liste, et la fin point à pause l'extraction, puis répétez jusqu'à la fin du fichier. Mon fichier à lire est formaté comme ceci:La lecture d'un gros fichier coûte trop de mémoire en Python 2.7

 
blabla... 
useless.... 
... 
/sign/ 
data block(e.g. 10 cols x 1000 rows) 
... blank line 
/sign/  
data block(e.g. 10 cols x 1000 rows) 
... blank line 
... 
EOF 

Appelons ce fichier « monfichier » et mon extrait de python:

f=open('myfile','r') 
blocknum=0 #number the data block 
data=[] 
while True: 
     # find the extract begnning 
     while not f.readline().startswith('/sign/'):pass 
     # creat multidimensional list to store data block 
     data=append([]) 
     blocknum +=1 
     line=f.readline() 

     while line.strip(): 
     # check if the line is a blank line, i.e the end of one block 
       data[blocknum-1].append(["2.6E" %float(x) for x in line.split()]) 
       line = f.readline() 
     print "Read Block %d" %blocknum 
     if not f.readline(): break 

Le résultat a été en cours d'exécution qui extraient 500M consomment presque 2 Go de RAM , Je ne peut pas comprendre, quelqu'un aide! Merci beaucoup!

+4

Veuillez vérifier votre code. Il a différents problèmes de formatage, de sémantique et de syntaxe (d'où vient l'appendice?). Pensez aussi à utiliser l'indentation standard en python (4 espaces) et n'écrivez pas plus d'une instruction sur la même ligne. – GaretJax

+0

Pourriez-vous également afficher quelques lignes d'un bloc de données typique? – NPE

Répondre

0

Vous avez pas mal de lignes ambiguës non-pythoniques dans votre code. Je ne sais pas, mais pense que vous pouvez modifier votre code comme suit d'abord, puis vérifier à nouveau contre l'utilisation de la mémoire:

data=[] 

with open('myfile','r') as f: 
    for line in f: 
     # find the extract beginning - think you can add here more parameters to check 
     if not line.strip() or line.startswith('/sign/'): 
      continue 
     data.append(["%2.6E" % float(x) for x in line.strip().split()]) 

Mais je pense que ce code utilisera également beaucoup de mémoire - si vous n'avez pas vraiment besoin de stocker toutes les données lues dans le fichier, vous pouvez modifier le code pour utiliser l'expression du générateur et poursuivre les données du fichier ligne par ligne - cela permettrait d'économiser votre mémoire, je suppose.

Questions connexes