Estoy leyendo un archivo CSV con 8 columnas en el marco de datos de Pandas. La columna final contiene un mensaje de error, algunos de los cuales contienen comas. Esto hace que la lectura del archivo falle con el error ParserError: Error tokenizing data. C error: Expected 8 fields in line 21922, saw 9
¿Hay alguna manera de ignorar todas las comas después del octavo campo, en lugar de tener que revisar el archivo y eliminar el exceso de comas?
Código para leer el archivo:
import pandas as pd df = pd.read_csv('C:\\somepath\\output.csv')Línea que funciona:
061AE,Active,001,2017_02_24 15_18_01,00006,1,00013,some messageLínea que falla:
061AE,Active,001,2017_02_24 15_18_01,00006,1,00013,longer message, with commasPuede usar re.sub para reemplazar las primeras comas con, digamos, '|', guarde los resultados intermedios en un StringIO y luego procese eso.
import pandas as pd from io import StringIO import re for_pd = StringIO() with open('MikeS159.csv') as mike: for line in mike: new_line = re.sub(r',', '|', line.rstrip(), count=7) print (new_line, file=for_pd) for_pd.seek(0) df = pd.read_csv(for_pd, sep='|', header=None) print (df)Puse las dos líneas de su pregunta en un archivo para obtener este resultado.
0 1 2 3 4 5 6 \ 0 061AE Active 1 2017_02_24 15_18_01 6 1 13 1 061AE Active 1 2017_02_24 15_18_01 6 1 13 7 0 some message 1 longer message, with commasPuede usar el parámetro usecols en la función read_csv para limitar las columnas en las que lee. Por ejemplo:
import pandas as pd pd.read_csv(path, usecols=range(8))si solo quieres leer las primeras 8 columnas.
Puede tomar una foto en esta rotonda publicada en la página de problemas de Pandas :
import csv import pandas as pd import numpy as np df = pd.read_csv('filename.csv', parse_dates=True, dtype=Object, delimiter="\t", quoting=csv.QUOTE_NONE, encoding='utf-8')También puede preprocesar los datos, básicamente cambiando las primeras 7 (0 a 6, ambas inclusive) comas a punto y coma, y dejando las siguientes como comas* usando algo como:
to_write = [] counter = 0 with open("sampleCSV.csv", "r") as f: for line in f: while counter < 7: line = list(line) line[line.index(",")] = ";" counter += 1 counter = 0 to_write.append("".join(line)) Ahora puede leer esta lista to_write como un objeto Pandas como
data = pd.DataFrame(to_write) data = pd.DataFrame(data[0].str.split(";").values.tolist()), o escríbalo nuevamente en un csv y léalo usando pandas con un delimitador de punto y coma como read_csv(csv_path, sep=';') .
Redacté esto rápidamente sin pruebas rigurosas, pero debería darle algunas ideas para probar. Por favor comente si ayuda o no, y lo editaré.
*Otra opción es eliminar todas las comas después del 7 y seguir usando el separador de coma. De cualquier manera, el punto es diferenciar los primeros 7 delimitadores de la puntuación posterior.