pandas read_csv y filtrar columnas con usecols

Tengo un archivo csv que no aparece correctamente con pandas.read_csv cuando filtro las columnas con usecols y uso varios índices.

 import pandas as pd csv = r"""dummy,date,loc,x bar,20090101,a,1 bar,20090102,a,3 bar,20090103,a,5 bar,20090101,b,1 bar,20090102,b,3 bar,20090103,b,5""" f = open('foo.csv', 'w') f.write(csv) f.close() df1 = pd.read_csv('foo.csv', header=0, names=["dummy", "date", "loc", "x"], index_col=["date", "loc"], usecols=["dummy", "date", "loc", "x"], parse_dates=["date"]) print df1 # Ignore the dummy columns df2 = pd.read_csv('foo.csv', index_col=["date", "loc"], usecols=["date", "loc", "x"], # <----------- Changed parse_dates=["date"], header=0, names=["dummy", "date", "loc", "x"]) print df2 

Espero que df1 y df2 sean iguales, excepto por la columna ficticia que falta, pero las columnas están mal etiquetadas. También la fecha se analiza como una fecha.

 In [118]: %run test.py dummy x date loc 2009-01-01 a bar 1 2009-01-02 a bar 3 2009-01-03 a bar 5 2009-01-01 b bar 1 2009-01-02 b bar 3 2009-01-03 b bar 5 date date loc a 1 20090101 3 20090102 5 20090103 b 1 20090101 3 20090102 5 20090103 

Usar números de columna en lugar de nombres me da el mismo problema. Puedo solucionar el problema eliminando la columna ficticia después del paso read_csv, pero estoy tratando de entender qué está mal. Estoy usando pandas 0.10.1.

Editar: arreglado mal uso del encabezado.

La respuesta de @chip pierde completamente el punto de dos argumentos de palabras clave.

  • los nombres solo son necesarios cuando no hay encabezado y desea especificar otros argumentos utilizando nombres de columna en lugar de índices enteros.
  • usecols debe proporcionar un filtro antes de leer todo el DataFrame en la memoria; si se usa correctamente, nunca debería haber una necesidad de eliminar columnas después de leer.

Esta solución corrige esas rarezas:

 import pandas as pd from StringIO import StringIO csv = r"""dummy,date,loc,x bar,20090101,a,1 bar,20090102,a,3 bar,20090103,a,5 bar,20090101,b,1 bar,20090102,b,3 bar,20090103,b,5""" df = pd.read_csv(StringIO(csv), header=0, index_col=["date", "loc"], usecols=["date", "loc", "x"], parse_dates=["date"]) 

Lo que nos da:

  x date loc 2009-01-01 a 1 2009-01-02 a 3 2009-01-03 a 5 2009-01-01 b 1 2009-01-02 b 3 2009-01-03 b 5 

Este código logra lo que quieres — también es extraño y ciertamente buggy:

Observé que funciona cuando:

a) especificas el index_col rel. a la cantidad de columnas que realmente utiliza, por lo que sus tres columnas en este ejemplo, no cuatro (se suelta y se empieza a contar desde ese momento)

b) lo mismo para las parse_dates de parse_dates

c) no es así para usecols 😉 por razones obvias

d) Aquí adapté los names para reflejar este comportamiento.

 import pandas as pd from StringIO import StringIO csv = """dummy,date,loc,x bar,20090101,a,1 bar,20090102,a,3 bar,20090103,a,5 bar,20090101,b,1 bar,20090102,b,3 bar,20090103,b,5 """ df = pd.read_csv(StringIO(csv), index_col=[0,1], usecols=[1,2,3], parse_dates=[0], header=0, names=["date", "loc", "", "x"]) print df 

que imprime

  x date loc 2009-01-01 a 1 2009-01-02 a 3 2009-01-03 a 5 2009-01-01 b 1 2009-01-02 b 3 2009-01-03 b 5 

Si su archivo csv contiene datos adicionales, las columnas se pueden eliminar del DataFrame después de la importación.

 import pandas as pd from StringIO import StringIO csv = r"""dummy,date,loc,x bar,20090101,a,1 bar,20090102,a,3 bar,20090103,a,5 bar,20090101,b,1 bar,20090102,b,3 bar,20090103,b,5""" df = pd.read_csv(StringIO(csv), index_col=["date", "loc"], usecols=["dummy", "date", "loc", "x"], parse_dates=["date"], header=0, names=["dummy", "date", "loc", "x"]) del df['dummy'] 

Lo que nos da:

  x date loc 2009-01-01 a 1 2009-01-02 a 3 2009-01-03 a 5 2009-01-01 b 1 2009-01-02 b 3 2009-01-03 b 5 

importe primero csv y use csv.DictReader es fácil de procesar …