2012-02-12 16 views
20

Tengo un montón de archivos CSV con gzip que me gustaría abrir para su inspección usando el lector CSV incorporado en Python. Me gustaría hacer esto sin tener que primero descomprimirlos manualmente en el disco. Supongo que de alguna manera quiero obtener una secuencia de los datos sin comprimir, y pasar esto al lector CSV. ¿Es esto posible en Python?Uso de csvreader contra un archivo comprimido en Python

+0

Además de las soluciones nativas de Python aquí, 'paquete pandas' tiene [' read_csv'] (https : //pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html) reader con compatibilidad gzip – smci

Respuesta

26

utilizar el módulo gzip:

with gzip.open(filename) as f: 
    reader = csv.reader(f) 
    #... 
+0

Si 'filename = 'tzaman.csv'' luego hace que el archivo' tzaman.csv' que es un archivo de almacenamiento, y contiene otro archivo 'tzaman.csv' que en realidad es un archivo csv. si lo llamamos 'abc.zip', entonces agrega' abc.zip' que es un zip y contiene un archivo 'abc.zip' que en realidad es un csv. ¿Qué hacer? – Clayton

+0

¿No comprime el archivo? – Clayton

+1

No crea un archivo. Gzip es solo un compresor de flujo. El nombre del archivo se debe llamar 'tzsman.csv.gz' para ayudar a identificar el tipo de archivo. Además, la biblioteca gzip no admite la instrucción with en Python 2.6.8. – Doug

6

una solución más completa:

import csv, gzip 
class GZipCSVReader: 
    def __init__(self, filename): 
     self.gzfile = gzip.open(filename) 
     self.reader = csv.DictReader(self.gzfile) 
    def next(self): 
     return self.reader.next() 
    def close(self): 
     self.gzfile.close() 
    def __iter__(self): 
     return self.reader.__iter__() 

ahora se puede utilizar de esta manera:

r = GZipCSVReader('my.csv') 
for map in r: 
    for k,v in map: 
     print k,v 
r.close() 
+0

aseado. Más fácil si puede agregar '__enter _/__ exit __()' métodos de gestor de contexto para que pueda usarse con la instrucción 'with'. – smci

19

He probado la versión anterior para escribir y leer, y no funcionó en Python 3.3 debido a un error de "bytes". Sin embargo, después de un poco de prueba y error, pude hacer que funcionara lo siguiente. Tal vez también ayuda a los demás:

import csv 
import gzip 
import io 


with gzip.open("test.gz", "w") as file: 
    writer = csv.writer(io.TextIOWrapper(file, newline="", write_through=True)) 
    writer.writerow([1, 2, 3]) 
    writer.writerow([4, 5, 6]) 

with gzip.open("test.gz", "r") as file: 
    reader = csv.reader(io.TextIOWrapper(file, newline="")) 
    print(list(reader)) 

Como amohr indica, las siguientes obras, así:

import gzip, csv 

with gzip.open("test.gz", "wt", newline="") as file: 
    writer = csv.writer(file) 
    writer.writerow([1, 2, 3]) 
    writer.writerow([4, 5, 6]) 

with gzip.open("test.gz", "rt", newline="") as file: 
    reader = csv.reader(file) 
    print(list(reader)) 
+0

@Gerenuk ¡funciona como un encanto! – ZuLu

+0

Esta solución también funciona con el 'io.BufferedReader' que podría ser más rápido según algunos [puntos de referencia] (http://ebnj.net/pythongzipbenchmarks/). Simplemente envuelva 'gzip.open' con' io.BufferedReader' haciéndolo 'con io.BufferedReader (gzip.open (" test.gz ", 'r')) como archivo:' –

+2

, puede omitir TextIOWrapper/BufferedReader si usa gzip.open (mode = 'rt' – amohr

Cuestiones relacionadas