Python: omite las líneas de comentario marcadas con # en csv.DictReader

El procesamiento de archivos CSV con csv.DictReader es excelente, pero tengo archivos CSV con líneas de comentarios (indicado por un hash al comienzo de una línea), por ejemplo:

 # tamaño de paso = 1.61853
 val0, val1, val2, hibridación, temperatura, smattr
 0.206895,0.797923,0.202077,0.631199,0.368801,0.311052,0.688948,0.597237,0.402763
 -169.32,1,1.61853,2.04069e-92,1,0.000906546,0.999093,0.241356,0.758644,0.202382
 # adaptación terminada

El módulo csv no incluye ninguna forma de omitir tales líneas .

Fácilmente podría hacer algo intrépido, pero imagino que hay una buena manera de envolver un csv.DicReader alrededor de algún otro objeto iterador, que preprocesa para descartar las líneas.

En realidad esto funciona muy bien con el filter :

 import csv fp = open('samples.csv') rdr = csv.DictReader(filter(lambda row: row[0]!='#', fp)) for row in rdr: print(row) fp.close() 

Buena pregunta y un buen ejemplo de cómo la biblioteca CSV de Python carece de una funcionalidad importante, como el manejo de comentarios básicos (no es raro en la parte superior de los archivos CSV). Si bien la solución de Dan Stowell funciona para el caso específico del OP, está limitada porque # debe aparecer como el primer símbolo. Una solución más genérica sería:

 def decomment(csvfile): for row in csvfile: raw = row.split('#')[0].strip() if raw: yield raw with open('dummy.csv') as csvfile: reader = csv.reader(decomment(csvfile)) for row in reader: print(row) 

Como ejemplo, el siguiente archivo dummy.csv :

 # comment # comment a,b,c # comment 1,2,3 10,20,30 # comment 

devoluciones

 ['a', 'b', 'c'] ['1', '2', '3'] ['10', '20', '30'] 

Por supuesto, esto funciona igual de bien con csv.DictReader() .

Otra forma de leer un archivo CSV es usando pandas

Aquí hay un código de ejemplo:

 df = pd.read_csv('test.csv', sep=',', # field separator comment='#', # comment index_col=0, # number or label of index column skipinitialspace=True, skip_blank_lines=True, error_bad_lines=False, warn_bad_lines=True ).sort_index() print(df) df.fillna('no value', inplace=True) # replace NaN with 'no value' print(df) 

Para este archivo csv:

 a,b,c,d,e 1,,16,,55#,,65##77 8,77,77,,16#86,18# #This is a comment 13,19,25,28,82 

obtendremos esta salida:

  bcde a 1 NaN 16 NaN 55 8 77.0 77 NaN 16 13 19.0 25 28.0 82 bcde a 1 no value 16 no value 55 8 77 77 no value 16 13 19 25 28 82