¿Cómo omitir los encabezados al procesar un archivo csv usando Python?

6 minutos de lectura

Estoy usando el código mencionado a continuación para editar un csv usando Python. Las funciones llamadas en el código forman la parte superior del código.

Problema: quiero que el código mencionado a continuación comience a editar el csv desde la segunda fila, quiero que excluya la primera fila que contiene encabezados. En este momento, está aplicando las funciones solo en la primera fila y mi fila de encabezado está cambiando.

in_file = open("tmob_notcleaned.csv", "rb")
reader = csv.reader(in_file)
out_file = open("tmob_cleaned.csv", "wb")
writer = csv.writer(out_file)
row = 1
for row in reader:
    row[13] = handle_color(row[10])[1].replace(" - ","").strip()
    row[10] = handle_color(row[10])[0].replace("-","").replace("(","").replace(")","").strip()
    row[14] = handle_gb(row[10])[1].replace("-","").replace(" ","").replace("GB","").strip()
    row[10] = handle_gb(row[10])[0].strip()
    row[9] = handle_oem(row[10])[1].replace("Blackberry","RIM").replace("TMobile","T-Mobile").strip()
    row[15] = handle_addon(row[10])[1].strip()
    row[10] = handle_addon(row[10])[0].replace(" by","").replace("FREE","").strip()
    writer.writerow(row)
in_file.close()    
out_file.close()

Traté de resolver este problema inicializando row variable a 1 pero no funcionó.

Por favor, ayúdame a resolver este problema.

  • posible duplicado de Al procesar datos CSV, ¿cómo ignoro la primera línea de datos?

    – Luis

    19 de agosto de 2015 a las 14:21

Avatar de usuario de Martijn Pieters
Martijn Pieters

Su reader variable es iterable, al recorrerla recupera las filas.

Para que salte un elemento antes de su ciclo, simplemente llame next(reader, None) e ignorar el valor de retorno.

También puede simplificar un poco su código; use los archivos abiertos como administradores de contexto para que se cierren automáticamente:

with open("tmob_notcleaned.csv", "rb") as infile, open("tmob_cleaned.csv", "wb") as outfile:
   reader = csv.reader(infile)
   next(reader, None)  # skip the headers
   writer = csv.writer(outfile)
   for row in reader:
       # process each row
       writer.writerow(row)

# no need to close, the files are closed automatically when you get to this point.

Si desea escribir el encabezado en el archivo de salida sin procesar, eso también es fácil, pase la salida de next() a writer.writerow():

headers = next(reader, None)  # returns the headers or `None` if the input is empty
if headers:
    writer.writerow(headers)

  • Una alternativa también es utilizar for row in islice(reader, 1, None) – aunque menos explícito que next para la mayoría de los trabajos simples de “omitir una línea”, para omitir varias filas de encabezado (u obtener solo ciertos fragmentos, etc.) es bastante útil

    –Jon Clements

    10 de enero de 2013 a las 12:12


  • consideraría usar try: writer.write(next(reader))... except StopIteration: # handle empty reader

    –Jon Clements

    10 de enero de 2013 a las 13:07

  • @JonClements: Quizás. Esto funciona bastante bien sin tener que enseñar sobre try: / except:.

    – Martijn Pieters

    10 de enero de 2013 a las 13:09

  • @JonClements: Ventaja de explícito next iteración es que es “gratis”; islice envolvería el reader Siempre agregando (una cantidad ciertamente muy pequeña de) gastos generales a cada iteración. los consume receta de itertools se puede usar para omitir muchos valores rápidamente, sin agregar ajuste al uso posterior, en el caso en que el islice tendría un start pero no endpor lo que la sobrecarga no le está ganando nada.

    – ShadowRanger

    5 de enero de 2016 a las 14:37


Otra forma de resolver esto es usar la clase DictReader, que “salta” la fila del encabezado y la usa para permitir la indexación con nombre.

Dado “foo.csv” de la siguiente manera:

FirstColumn,SecondColumn
asdf,1234
qwer,5678

Use DictReader así:

import csv
with open('foo.csv') as f:
    reader = csv.DictReader(f, delimiter=",")
    for row in reader:
        print(row['FirstColumn'])  # Access by column header instead of column number
        print(row['SecondColumn'])

  • Siento que esta es la respuesta real, ya que la pregunta parece ser un ejemplo de problema XY.

    – Marius Siuram

    23 de septiembre de 2016 a las 8:28

  • DictReader es definitivamente el camino a seguir

    –Javier Arias

    15 de agosto de 2017 a las 11:43

  • Es importante tener en cuenta que esto solo funciona si omite el parámetro de nombres de campo al construir el DictReader. Según la documentación: If the fieldnames parameter is omitted, the values in the first row of the file f will be used as the fieldnames. Ver docs.python.org/2/library/csv.html

    – BuvinJ

    1 de marzo de 2018 a las 14:14


Haciendo row=1 no cambiará nada, porque simplemente lo sobrescribirá con los resultados del ciclo.

Quieres hacer next(reader) para saltar una fila.

  • Intenté cambiarlo a for row in next(reader): pero me esta dando IndexError: string index out of range error

    usuario1915050

    10 de enero de 2013 a las 12:09

  • Úselo antes del bucle for: next(reader); for row in reader: ….

    – dlazesz

    7 mayo 2020 a las 14:01

avatar de usuario de bitbang
bitbang

Simplemente iterar una vez con next()

with open(filename) as file:

    csvreaded = csv.reader(file)
    header = next(csvreaded)

    for row in csvreaded:
        empty_list.append(row) #your csv list without header  

o usar [1:] al final del objeto del lector

with open(filename) as file:

    csvreaded = csv.reader(file)
    header = next(csvreaded)

    for row in csvreaded[1:]:
        empty_list.append(row) #your csv list without header  

Avatar de usuario de Darío López Padial
Darío López Padial

Inspirado en la respuesta de Martijn Pieters.

En caso de que solo necesite eliminar el encabezado de la csv archivo, puede trabajar de manera más eficiente si escribe usando la biblioteca estándar de E/S de archivos de Python, evitando escribir con la biblioteca de Python CSV:

with open("tmob_notcleaned.csv", "rb") as infile, open("tmob_cleaned.csv", "wb") as outfile:
   next(infile)  # skip the headers
   outfile.write(infile.read())

  • Pareces pasar por alto el # process each row parte de la respuesta de Martijn, que representa todo lo que el operador quiere con las filas, así como el hecho de que el operador quiere un archivo csv como salida? Por supuesto que puede evitar el uso de la csv módulo en total. Pero cuál es el punto, es desde el estándar ¿biblioteca?

    – Timo

    30 oct 2020 a las 20:52


  • En mi caso, solo quiero eliminar el encabezado de la csv archivo, y no quiero procesar nada. Por esta razón, escribo usando la biblioteca estándar, porque es más rápida. Editaré mi comentario para ser más claro.

    – Darío López Padial

    3 de noviembre de 2020 a las 9:56

  • Ya veo. En ese caso no necesitas el csv módulo en absoluto: Sólo next(infile) sin instanciar un csv.reader debería hacerlo (la salida de open es también un iterador).

    – Timo

    3 de noviembre de 2020 a las 12:27

  • Pareces pasar por alto el # process each row parte de la respuesta de Martijn, que representa todo lo que el operador quiere con las filas, así como el hecho de que el operador quiere un archivo csv como salida? Por supuesto que puede evitar el uso de la csv módulo en total. Pero cuál es el punto, es desde el estándar ¿biblioteca?

    – Timo

    30 oct 2020 a las 20:52


  • En mi caso, solo quiero eliminar el encabezado de la csv archivo, y no quiero procesar nada. Por esta razón, escribo usando la biblioteca estándar, porque es más rápida. Editaré mi comentario para ser más claro.

    – Darío López Padial

    3 de noviembre de 2020 a las 9:56

  • Ya veo. En ese caso no necesitas el csv módulo en absoluto: Sólo next(infile) sin instanciar un csv.reader debería hacerlo (la salida de open es también un iterador).

    – Timo

    3 de noviembre de 2020 a las 12:27

¿Ha sido útil esta solución?