tablas - ¿Cuál es una forma muy general de leer.csv en Python y pandas?
leer archivo csv con pandas (2)
Tengo un archivo .csv con filas con múltiples longitudes de columnas.
import pandas as pd
df = pd.read_csv(infile, header=None)
devuelve el
ParserError: Error tokenizing data. C error: Expected 6 fields in line 8, saw 8
error. Sé que puedo usar el
names=my_cols
opción en la llamada read_csv, pero seguramente tiene que haber algo más "pitónico" que eso? Además, esta no es una pregunta duplicada, ya que
error_bad_lines=False
hace que las líneas se salten (lo cual no es deseado). El .csv tiene el siguiente aspecto ::
Anne,Beth,Caroline,Ernie,Frank,Hannah
Beth,Caroline,David,Ernie
Caroline,Hannah
David,,Anne,Beth,Caroline,Ernie
Ernie,Anne,Beth,Frank,George
Frank,Anne,Caroline,Hannah
George,
Hannah,Anne,Beth,Caroline,David,Ernie,Frank,George
OK, algo inspirado por esta pregunta relacionada: Pandas números variables de columnas a la matriz binaria
Por lo tanto, lea en el csv pero anule el separador en una pestaña para que no intente dividir los nombres:
In[7]:
import pandas as pd
import io
t="""Anne,Beth,Caroline,Ernie,Frank,Hannah
Beth,Caroline,David,Ernie
Caroline,Hannah
David,,Anne,Beth,Caroline,Ernie
Ernie,Anne,Beth,Frank,George
Frank,Anne,Caroline,Hannah
George,
Hannah,Anne,Beth,Caroline,David,Ernie,Frank,George"""
df = pd.read_csv(io.StringIO(t), sep=''/t'', header=None)
df
Out[7]:
0
0 Anne,Beth,Caroline,Ernie,Frank,Hannah
1 Beth,Caroline,David,Ernie
2 Caroline,Hannah
3 David,,Anne,Beth,Caroline,Ernie
4 Ernie,Anne,Beth,Frank,George
5 Frank,Anne,Caroline,Hannah
6 George,
7 Hannah,Anne,Beth,Caroline,David,Ernie,Frank,Ge...
Ahora podemos usar str.split
con expand=True
para expandir los nombres en sus propias columnas:
In[8]:
df[0].str.split('','', expand=True)
Out[8]:
0 1 2 3 4 5 6 7
0 Anne Beth Caroline Ernie Frank Hannah None None
1 Beth Caroline David Ernie None None None None
2 Caroline Hannah None None None None None None
3 David Anne Beth Caroline Ernie None None
4 Ernie Anne Beth Frank George None None None
5 Frank Anne Caroline Hannah None None None None
6 George None None None None None None
7 Hannah Anne Beth Caroline David Ernie Frank George
Entonces, para que quede claro, modifique su línea read_csv
a esto:
df = pd.read_csv(infile, header=None, sep=''/t'')
y luego hacer el str.split
como arriba
Uno puede hacer algo de manipulación con la csv antes de usar pandas.
# load data into list
with open(''new_data.txt'', ''r'') as fil:
data = fil.readlines()
# remove line breaks from string entries
data = [ x.replace(''/r/n'', '''') for x in data]
data = [ x.replace(''/n'', '''') for x in data]
# calculate the number of columns
total_cols = max([x.count('','') for x in data])
# add '','' to end of list depending on how many are needed
new_data = [x + '',''*(total_cols-x.count('','')) for x in data]
# save data
with open(''save_data.txt'', ''w'') as outp:
outp.write(''/n''.join(new_data))
# read it in as you did.
pd.read_csv(''save_data.txt'', header=None)
Este es un pitón en bruto, pero debería funcionar. Lo limpiaré cuando tenga tiempo.
O usa la otra respuesta, está ordenado como es.