read_csv read huge chunk python list csv chunks

python - chunk - pandas read huge file



¿Cómo dividir la lectura de un archivo csv grande en trozos de tamaño uniforme en Python? (3)

No hay una buena manera de hacer esto para todos los archivos .csv . Debería poder dividir el archivo en file.seek utilizando file.seek para omitir una sección del archivo. Luego, debe escanear un byte a la vez para encontrar el final de la fila. Puede procesar los dos trozos de forma independiente. Algo como el siguiente código (no probado) debería ayudarte a comenzar.

file_one = open(''foo.csv'') file_two = open(''foo.csv'') file_two.seek(0, 2) # seek to the end of the file sz = file_two.tell() # fetch the offset file_two.seek(sz / 2) # seek back to the middle chr = '''' while chr != ''/n'': chr = file_two.read(1) # file_two is now positioned at the start of a record segment_one = csv.reader(file_one) segment_two = csv.reader(file_two)

No estoy seguro de cómo puede saber que ha terminado de atravesar segment_one . Si tiene una columna en el CSV que es un identificador de fila, puede detener el procesamiento de segment_one cuando encuentre el identificador de fila de la primera fila en segment_two .

En un básico tuve el siguiente proceso.

import csv reader = csv.reader(open(''huge_file.csv'', ''rb'')) for line in reader: process_line(line)

Vea esta question relacionada. Quiero enviar la línea de proceso cada 100 filas, para implementar la fragmentación por lotes.

El problema acerca de la implementación de la respuesta relacionada es que el objeto csv no se puede suscribir y no puede usar len.

>>> import csv >>> reader = csv.reader(open(''dataimport/tests/financial_sample.csv'', ''rb'')) >>> len(reader) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: object of type ''_csv.reader'' has no len() >>> reader[10:] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: ''_csv.reader'' object is unsubscriptable >>> reader[10] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: ''_csv.reader'' object is unsubscriptable

¿Como puedo resolver esto?


Podemos usar el módulo pandas para manejar estos grandes archivos csv.

df = pd.DataFrame() temp = pd.read_csv(''BIG_File.csv'', iterator=True, chunksize=1000) df = pd.concat(temp, ignore_index=True)


Simplemente haga que su reader subíndice compaginándolo en una list . Obviamente, esto se romperá en archivos realmente grandes (ver alternativas en las actualizaciones a continuación):

>>> reader = csv.reader(open(''big.csv'', ''rb'')) >>> lines = list(reader) >>> print lines[:100] ...

Más información: question

Actualización 1 (versión de lista): Otra forma posible sería simplemente procesar cada mandril, a medida que llega al iterar sobre las líneas:

#!/usr/bin/env python import csv reader = csv.reader(open(''4956984.csv'', ''rb'')) chunk, chunksize = [], 100 def process_chunk(chuck): print len(chuck) # do something useful ... for i, line in enumerate(reader): if (i % chunksize == 0 and i > 0): process_chunk(chunk) del chunk[:] chunk.append(line) # process the remainder process_chunk(chunk)

Actualización 2 (versión del generador): no lo he evaluado, pero quizás pueda aumentar el rendimiento utilizando un generador de trozos:

#!/usr/bin/env python import csv reader = csv.reader(open(''4956984.csv'', ''rb'')) def gen_chunks(reader, chunksize=100): """ Chunk generator. Take a CSV `reader` and yield `chunksize` sized slices. """ chunk = [] for i, line in enumerate(reader): if (i % chunksize == 0 and i > 0): yield chunk del chunk[:] chunk.append(line) yield chunk for chunk in gen_chunks(reader): print chunk # process chunk # test gen_chunk on some dummy sequence: for chunk in gen_chunks(range(10), chunksize=3): print chunk # process chunk # => yields # [0, 1, 2] # [3, 4, 5] # [6, 7, 8] # [9]