python - example - Dtypes datetime en pandas read_csv
series to datetime pandas (4)
Estoy leyendo en un archivo csv con varias columnas de fecha y hora. Tendría que establecer los tipos de datos al leer el archivo, pero las fechas parecen ser un problema. Por ejemplo:
headers = [''col1'', ''col2'', ''col3'', ''col4'']
dtypes = [''datetime'', ''datetime'', ''str'', ''float'']
pd.read_csv(file, sep=''/t'', header=None, names=headers, dtype=dtypes)
Cuando se ejecuta da un error:
TypeError: data type "datetime" not understood
La conversión de columnas después del hecho, vía pandas.to_datetime () no es una opción. No puedo saber qué columnas serán objetos de fecha y hora. Esa información puede cambiar y proviene de lo que informa mi lista de tipos.
Alternativamente, he intentado cargar el archivo csv con numpy.genfromtxt, establecer los dtypes en esa función y luego convertirlo a pandas.dataframe pero desdibuja los datos. ¡Cualquier ayuda es muy apreciada!
Por qué no funciona
No hay un tipo de fecha y hora que se establezca para read_csv, ya que los archivos csv solo pueden contener cadenas, enteros y flotantes.
Establecer un tipo de dtpe en datetime hará que los pandas interpreten el datetime como un objeto, lo que significa que terminará con una cadena.
Pandas forma de resolver esto
La función pandas.read_csv()
tiene un argumento de palabra clave llamado parse_dates
Al usar esto puedes sobre la marcha convertir cadenas, flotantes o enteros en date_parser
usando el predeterminado date_parser
( dateutil.parser.parser
)
headers = [''col1'', ''col2'', ''col3'', ''col4'']
dtypes = {''col1'': ''str'', ''col2'': ''str'', ''col3'': ''str'', ''col4'': ''float''}
parse_dates = [''col1'', ''col2'']
pd.read_csv(file, sep=''/t'', header=None, names=headers, dtype=dtypes, parse_dates=parse_dates)
Esto hará que los pandas lean col1
y col2
como cadenas, lo que es más probable ("2016-05-05", etc.) y después de haber leído la cadena, el fecha_parser de cada columna actuará sobre esa cadena y devolverá lo que sea la función vuelve.
Definición de su propia función de análisis de fecha:
La función pandas.read_csv()
también tiene un argumento de palabra clave llamado date_parser
Establecer esto en una función lambda hará que esa función en particular se use para el análisis de las fechas.
ADVERTENCIA DE GOTCHA
Tienes que darle la función, no la ejecución de la función, por lo tanto esto es correcto
date_parser = pd.datetools.to_datetime
Esto es incorrecto
date_parser = pd.datetools.to_datetime()
Actualización de Pandas 0.22
pd.datetools.to_datetime
ha sido reubicado a date_parser = pd.to_datetime
Gracias @stackoverYC
Ahora hay un parámetro parse_dates que puede pasar a read_csv que le permite listar los nombres de las columnas que desea tratar como fechas. Entonces, la mejor manera ahora para OP es:
dateCols = [''col1'', ''col2'']
pd.read_csv(file, sep=''/t'', header=None, names=headers, parse_dates=dateCols)
pandas.read_csv() bastante elegante ...
Intenté usar la opción dtypes = [datetime, ...], pero
import pandas as pd
from datetime import datetime
headers = [''col1'', ''col2'', ''col3'', ''col4'']
dtypes = [datetime, datetime, str, float]
pd.read_csv(file, sep=''/t'', header=None, names=headers, dtype=dtypes)
Me encontré con el siguiente error:
TypeError: data type not understood
El único cambio que tuve que hacer fue reemplazar datetime con datetime.datetime
import pandas as pd
from datetime import datetime
headers = [''col1'', ''col2'', ''col3'', ''col4'']
dtypes = [datetime.datetime, datetime.datetime, str, float]
pd.read_csv(file, sep=''/t'', header=None, names=headers, dtype=dtypes)
Puede intentar pasar tipos reales en lugar de cadenas.
import pandas as pd
from datetime import datetime
headers = [''col1'', ''col2'', ''col3'', ''col4'']
dtypes = [datetime, datetime, str, float]
pd.read_csv(file, sep=''/t'', header=None, names=headers, dtype=dtypes)
Pero va a ser muy difícil diagnosticar esto sin tener que jugar con ninguno de sus datos.
Y realmente, es probable que desee que los pandas analicen las fechas en TimeStamps, por lo que podría ser:
pd.read_csv(file, sep=''/t'', header=None, names=headers, parse_dates=True)