python - read - ¿Cómo escribir una fila de encabezado con csv.DictWriter?
read csv python pandas (3)
Algunas opciones:
(1) Laboriosamente haga una asignación de identidad (es decir, no haga nada) dict fuera de sus nombres de campo para que csv.DictWriter pueda convertirlo de nuevo a una lista y pasarlo a una instancia de csv.writer.
(2) La documentación menciona "la instancia del writer
subyacente" ... así que simplemente úsela (ejemplo al final).
dw.writer.writerow(dw.fieldnames)
(3) Evite la sobrecarga de csv.Dictwriter y hágalo usted mismo con csv.writer
Escribir datos:
w.writerow([d[k] for k in fieldnames])
o
w.writerow([d.get(k, restval) for k in fieldnames])
En lugar de la "funcionalidad" de extrasaction
, preferiría codificarlo yo mismo; de esa manera puede reportar TODOS los "extras" con las claves y valores, no solo con la primera clave adicional. Lo que es realmente una molestia con DictWriter es que si ha verificado las claves usted mismo cuando se está construyendo cada dict, debe recordar usar extrasaction = ''ignore''; de lo contrario, se va a LENTAMENTE (los nombres de los campos es una lista) repite el cheque:
wrong_fields = [k for k in rowdict if k not in self.fieldnames]
============
>>> f = open(''csvtest.csv'', ''wb'')
>>> import csv
>>> fns = ''foo bar zot''.split()
>>> dw = csv.DictWriter(f, fns, restval=''Huh?'')
# dw.writefieldnames(fns) -- no such animal
>>> dw.writerow(fns) # no such luck, it can''t imagine what to do with a list
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:/python26/lib/csv.py", line 144, in writerow
return self.writer.writerow(self._dict_to_list(rowdict))
File "C:/python26/lib/csv.py", line 141, in _dict_to_list
return [rowdict.get(key, self.restval) for key in self.fieldnames]
AttributeError: ''list'' object has no attribute ''get''
>>> dir(dw)
[''__doc__'', ''__init__'', ''__module__'', ''_dict_to_list'', ''extrasaction'', ''fieldnam
es'', ''restval'', ''writer'', ''writerow'', ''writerows'']
# eureka
>>> dw.writer.writerow(dw.fieldnames)
>>> dw.writerow({''foo'':''oof''})
>>> f.close()
>>> open(''csvtest.csv'', ''rb'').read()
''foo,bar,zot/r/noof,Huh?,Huh?/r/n''
>>>
Supongamos que tengo un objeto csv.DictReader
y quiero escribirlo como un archivo CSV. ¿Cómo puedo hacer esto?
Sé que puedo escribir las filas de datos de esta manera:
dr = csv.DictReader(open(f), delimiter=''/t'')
# process my dr object
# ...
# write out object
output = csv.DictWriter(open(f2, ''w''), delimiter=''/t'')
for item in dr:
output.writerow(item)
¿Pero cómo puedo incluir los nombres de campo?
Editar:
En 2.7 / 3.2 hay un nuevo método writeheader()
. Además, la respuesta de John Machin proporciona un método más simple para escribir la fila del encabezado.
Ejemplo simple de usar el método writeheader()
ahora disponible en 2.7 / 3.2:
from collections import OrderedDict
ordered_fieldnames = OrderedDict([(''field1'',None),(''field2'',None)])
with open(outfile,''wb'') as fou:
dw = csv.DictWriter(fou, delimiter=''/t'', fieldnames=ordered_fieldnames)
dw.writeheader()
# continue on to write data
La instancia de DictWriter requiere un argumento de nombres de campo.
De la documentación :
El parámetro de nombres de campo identifica el orden en el que los valores del diccionario pasados al método writerow () se escriben en el archivo csv.
Dicho de otra forma: se requiere el argumento Fieldnames porque los dictados de Python son intrínsecamente desordenados.
A continuación se muestra un ejemplo de cómo escribirías el encabezado y los datos en un archivo.
Nota: with
declaración fue agregada en 2.6. Si usa 2.5: from __future__ import with_statement
with open(infile,''rb'') as fin:
dr = csv.DictReader(fin, delimiter=''/t'')
# dr.fieldnames contains values from first row of `f`.
with open(outfile,''wb'') as fou:
dw = csv.DictWriter(fou, delimiter=''/t'', fieldnames=dr.fieldnames)
headers = {}
for n in dw.fieldnames:
headers[n] = n
dw.writerow(headers)
for row in dr:
dw.writerow(row)
Como @FM menciona en un comentario, puede condensar la escritura de encabezados en un solo trazo, por ejemplo:
with open(outfile,''wb'') as fou:
dw = csv.DictWriter(fou, delimiter=''/t'', fieldnames=dr.fieldnames)
dw.writerow(dict((fn,fn) for fn in dr.fieldnames))
for row in dr:
dw.writerow(row)
Otra forma de hacerlo sería agregar antes de agregar líneas en su salida, la siguiente línea:
output.writerow(dict(zip(dr.fieldnames, dr.fieldnames)))
El zip devolvería una lista de doublet que contiene el mismo valor. Esta lista podría usarse para iniciar un diccionario.