leer exportar datos crear columnas python file csv import delimiter

exportar - leer columnas en python



¿Puedo importar un archivo CSV e inferir automáticamente el delimitador? (5)

Dado un proyecto que trata con ambos, (coma) y | (barra vertical) archivos CSV delimitados, que están bien formados, intenté lo siguiente (como se indica en https://docs.python.org/2/library/csv.html#csv.Sniffer ):

dialect = csv.Sniffer().sniff(csvfile.read(1024), delimiters='',|'')

Sin embargo, en un archivo | -imimited, se devolvió la excepción "No se pudo determinar el delimitador". Parecía razonable especular que la heurística de oler podría funcionar mejor si cada línea tiene el mismo número de delimitadores (sin contar lo que pueda estar entre comillas). Entonces, en vez de leer los primeros 1024 bytes del archivo, intenté leer las dos primeras líneas en su totalidad:

temp_lines = csvfile.readline() + ''/n'' + csvfile.readline() dialect = csv.Sniffer().sniff(temp_lines, delimiters='',|'')

Hasta ahora, esto está funcionando bien para mí.

Quiero importar dos tipos de archivos CSV, algunos usan ";" para el delimitador y otros usan ",". Hasta ahora he estado cambiando entre las siguientes dos líneas:

reader=csv.reader(f,delimiter='';'')

o

reader=csv.reader(f,delimiter='','')

¿Es posible no especificar el delimitador y dejar que el programa verifique el delimitador correcto?

Las soluciones a continuación (Blender y sharth) parecen funcionar bien para archivos separados por comas (generados con Libroffice) pero no para archivos separados por punto y coma (generados con MS Office). Estas son las primeras líneas de un archivo separado por punto y coma:

ReleveAnnee;ReleveMois;NoOrdre;TitreRMC;AdopCSRegleVote;AdopCSAbs;AdoptCSContre;NoCELEX;ProposAnnee;ProposChrono;ProposOrigine;NoUniqueAnnee;NoUniqueType;NoUniqueChrono;PropoSplittee;Suite2LecturePE;Council PATH;Notes 1999;1;1;1999/83/EC: Council Decision of 18 January 1999 authorising the Kingdom of Denmark to apply or to continue to apply reductions in, or exemptions from, excise duties on certain mineral oils used for specific purposes, in accordance with the procedure provided for in Article 8(4) of Directive 92/81/EEC;U;;;31999D0083;1998;577;COM;NULL;CS;NULL;;;;Propos* are missing on Celex document 1999;1;2;1999/81/EC: Council Decision of 18 January 1999 authorising the Kingdom of Spain to apply a measure derogating from Articles 2 and 28a(1) of the Sixth Directive (77/388/EEC) on the harmonisation of the laws of the Member States relating to turnover taxes;U;;;31999D0081;1998;184;COM;NULL;CS;NULL;;;;Propos* are missing on Celex document


El módulo csv parece recomendar el uso del sniffer csv para este problema.

Dan el siguiente ejemplo, que he adaptado para su caso.

with open(''example.csv'', ''rb'') as csvfile: # python 3: ''r'',newline="" dialect = csv.Sniffer().sniff(csvfile.read(1024), delimiters=";,") csvfile.seek(0) reader = csv.reader(csvfile, dialect) # ... process CSV file contents here ...

Probémoslo.

[9:13am][wlynch@watermelon /tmp] cat example #!/usr/bin/env python import csv def parse(filename): with open(filename, ''rb'') as csvfile: dialect = csv.Sniffer().sniff(csvfile.read(), delimiters='';,'') csvfile.seek(0) reader = csv.reader(csvfile, dialect) for line in reader: print line def main(): print ''Comma Version:'' parse(''comma_separated.csv'') print print ''Semicolon Version:'' parse(''semicolon_separated.csv'') print print ''An example from the question (kingdom.csv)'' parse(''kingdom.csv'') if __name__ == ''__main__'': main()

Y nuestras entradas de muestra

[9:13am][wlynch@watermelon /tmp] cat comma_separated.csv test,box,foo round,the,bend [9:13am][wlynch@watermelon /tmp] cat semicolon_separated.csv round;the;bend who;are;you [9:22am][wlynch@watermelon /tmp] cat kingdom.csv ReleveAnnee;ReleveMois;NoOrdre;TitreRMC;AdopCSRegleVote;AdopCSAbs;AdoptCSContre;NoCELEX;ProposAnnee;ProposChrono;ProposOrigine;NoUniqueAnnee;NoUniqueType;NoUniqueChrono;PropoSplittee;Suite2LecturePE;Council PATH;Notes 1999;1;1;1999/83/EC: Council Decision of 18 January 1999 authorising the Kingdom of Denmark to apply or to continue to apply reductions in, or exemptions from, excise duties on certain mineral oils used for specific purposes, in accordance with the procedure provided for in Article 8(4) of Directive 92/81/EEC;U;;;31999D0083;1998;577;COM;NULL;CS;NULL;;;;Propos* are missing on Celex document 1999;1;2;1999/81/EC: Council Decision of 18 January 1999 authorising the Kingdom of Spain to apply a measure derogating from Articles 2 and 28a(1) of the Sixth Directive (77/388/EEC) on the harmonisation of the laws of the Member States relating to turnover taxes;U;;;31999D0081;1998;184;COM;NULL;CS;NULL;;;;Propos* are missing on Celex document

Y si ejecutamos el programa de ejemplo:

[9:14am][wlynch@watermelon /tmp] ./example Comma Version: [''test'', ''box'', ''foo''] [''round'', ''the'', ''bend''] Semicolon Version: [''round'', ''the'', ''bend''] [''who'', ''are'', ''you''] An example from the question (kingdom.csv) [''ReleveAnnee'', ''ReleveMois'', ''NoOrdre'', ''TitreRMC'', ''AdopCSRegleVote'', ''AdopCSAbs'', ''AdoptCSContre'', ''NoCELEX'', ''ProposAnnee'', ''ProposChrono'', ''ProposOrigine'', ''NoUniqueAnnee'', ''NoUniqueType'', ''NoUniqueChrono'', ''PropoSplittee'', ''Suite2LecturePE'', ''Council PATH'', ''Notes''] [''1999'', ''1'', ''1'', ''1999/83/EC: Council Decision of 18 January 1999 authorising the Kingdom of Denmark to apply or to continue to apply reductions in, or exemptions from, excise duties on certain mineral oils used for specific purposes, in accordance with the procedure provided for in Article 8(4) of Directive 92/81/EEC'', ''U'', '''', '''', ''31999D0083'', ''1998'', ''577'', ''COM'', ''NULL'', ''CS'', ''NULL'', '''', '''', '''', ''Propos* are missing on Celex document''] [''1999'', ''1'', ''2'', ''1999/81/EC: Council Decision of 18 January 1999 authorising the Kingdom of Spain to apply a measure derogating from Articles 2 and 28a(1) of the Sixth Directive (77/388/EEC) on the harmonisation of the laws of the Member States relating to turnover taxes'', ''U'', '''', '''', ''31999D0081'', ''1998'', ''184'', ''COM'', ''NULL'', ''CS'', ''NULL'', '''', '''', '''', ''Propos* are missing on Celex document'']

También es probable que valga la pena señalar qué versión de Python estoy usando.

[9:20am][wlynch@watermelon /tmp] python -V Python 2.7.2


No creo que pueda haber una solución perfectamente general para esto (una de las razones por las que podría usar , como delimitador es que algunos de mis campos de datos deben ser capaces de incluir ; ...). Una heurística simple para decidir podría ser simplemente leer la primera línea (o más), contar cuántos , y ; los caracteres que contiene (posiblemente ignorando las comillas internas, si lo que crea sus archivos .csv cita las entradas correcta y consistentemente), y adivine que el más frecuente de los dos es el delimitador correcto.


Para resolver el problema, he creado una función que lee la primera línea de un archivo (encabezado) y detecta el delimitador.

def detectDelimiter(csvFile): with open(csvFile, ''r'') as myCsvfile: header=myCsvfile.readline() if header.find(";")!=-1: return ";" if header.find(",")!=-1: return "," #default delimiter (MS Office export) return ";"


Y si estás usando DictReader puedes hacer eso:

#!/usr/bin/env python import csv def parse(filename): with open(filename, ''rb'') as csvfile: dialect = csv.Sniffer().sniff(csvfile.read(), delimiters='';,'') csvfile.seek(0) reader = csv.DictReader(csvfile, dialect=dialect) for line in reader: print(line[''ReleveAnnee''])

Usé esto con Python 3.5 y funcionó de esta manera.