2011-12-09 13 views
6

Estoy tratando con datos de gran tamaño, por lo que es muy importante encontrar una buena forma de leer datos. Estoy un poco confundido acerca de los diferentes métodos de lectura.Diferentes formas de leer datos grandes en python

1.f=gzip.open(file,'r') 
     for line in f: 
      process line 
    #how can I process nth line? can I? 
2.f=gzip.open(file,'r').readlines() 
    #f is a list 
    f[10000] 
    #we can process nth line 

3.f=gzip.open(file,'r') 
    while True: 
     linelist=list(islice(f,4)) 

4.for line in fileinput.input(): 
    process line 

¿Cuál es la diferencia entre 2 y 3? Solo encuentro que su uso de memoria es el mismo. islice() también necesita cargar primero todo el archivo en la memoria (pero más adelante tomarlo poco a poco). Y oigo que el 4to método consume menos memoria, en realidad se procesa poco a poco, ¿verdad? Para archivos de escala de 10GB, ¿qué método de lectura de archivos recomendaría? Cualquier pensamiento/información es bienvenida. thx

editar: Creo que uno de mi problema es que necesito seleccionar líneas específicas al azar algunas veces. dicen:

f1=open(inputfile1, 'r') 
while True: 
    line_group1 = list(islice(f1, 3)) 
    if not line_group1: 
     break 
    #then process specific lines say, the second line. 
    processed 2nd line 
    if (....): 
      LIST1.append(line_group1[0]) 
      LIST1.append(processed 2nd line) 
      LIST1.append(line_group1[2]) 

Y entonces algo. como

with open(file,'r') as f, 
    for line in f: 
     # process line 

puede que no funcione, ¿estoy en lo correcto?

+0

así que ¿es necesario tener acceso aleatorio a un archivo de texto grande? –

+0

Bueno, en realidad no necesariamente. Básicamente aún procesa línea por línea; o N líneas como un grupo. – user815408

Respuesta

4

Has olvidado -

with open(...) as f: 
    for line in f: 
     <do something with line> 

Los with identificadores de instrucción abrir y cerrar el archivo, incluso si se produce una excepción en el bloque interno. El for line in f trata el objeto de archivo f como iterable, que utiliza automáticamente la administración de memoria y IO con búfer para que no tenga que preocuparse por archivos grandes.

Ambos 2.3 no se recomiendan para archivos de gran tamaño, ya que leen & cargan todo el contenido del archivo en la memoria antes de que comience el procesamiento. Para leer archivos de gran tamaño, necesita encontrar formas de no leer todo el archivo de una sola vez.

Debe haber una, y preferiblemente solo una, forma obvia de hacerlo.

+0

No se pudo hacer +1 por segunda vez después de la edición de la cita de ZEN ... Sin embargo, ¡hecho de forma moral! ;) – mac

+0

thx, pero ¿puedes mirar mi edición? a veces necesito tomar una línea específica (por ejemplo, la línea 10000). Entonces, ¿cómo puedo hacer? – user815408

+0

simple, luego mantenga un 'contador' que es básicamente la línea num. Verifique si es 10000ma línea y realice su manejo especial. –

1

Puede utilizar enumerate para obtener un índice que permite repetir algo:

for idx, line in enumerate(f): 
    # process line 

simple y eficiente de la memoria. En realidad se puede utilizar islice también, e iterar sobre ella sin necesidad de convertir a una primera lista:

for line in islice(f,start,stop): 
    # process line 

Ninguno de los enfoques leerá el archivo en la memoria, ni crear una lista intermedia.

En cuanto a fileinput, es solo una clase de ayuda para el bucle rápido sobre la entrada estándar o una lista de archivos, no hay beneficio de la eficiencia de memoria para su uso.

Como señala Srikar, el uso de la declaración with es la forma preferida para abrir/cerrar un archivo.

+0

con islice (f, 4), si no hago una lista, ¿cómo puedo elegir fuera de la primera, segunda, tercera y cuarta líneas? (como hago en la publicación) – user815408

+0

Simplemente itere sobre ella normalmente, 'for line in islice (f, 4): print line' imprimirá las líneas 1,2,3,4. Si quería las líneas 2 a 5, podría usar 'islice (2,6)' en su lugar, etc. – zeekay

0

no sabe cuántas líneas hasta que lea y cuente cuántas \ n en ella. En 1, puede agregar una enumeración para obtener el número de línea.

Cuestiones relacionadas