tipos de fecha y hora en pandas read_csv

127

Estoy leyendo en un archivo csv con múltiples columnas de fecha y hora. Necesitaría configurar los tipos de datos al leer el archivo, pero las fechas y horas 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: no se entiende el tipo de datos "datetime"

Convertir columnas después del hecho, a través de 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 sea que informe mi lista de tipos.

Alternativamente, intenté cargar el archivo csv con numpy.genfromtxt, establecer los dtypes en esa función y luego convertirlo a pandas.dataframe pero confunde los datos. ¡Cualquier ayuda es muy apreciada!

user3221055
fuente

Respuestas:

273

Por que no funciona

No hay un dtype de fecha y hora para ser configurado para read_csv ya que los archivos csv solo pueden contener cadenas, enteros y flotantes.

Establecer un dtype en datetime hará que los pandas interpreten la fecha y hora como un objeto, lo que significa que terminará con una cadena.

La forma de Pandas de resolver esto

La pandas.read_csv()función tiene un argumento de palabra clave llamadoparse_dates

Con esto, puede convertir sobre la marcha cadenas, flotantes o enteros en fechas y horas usando el valor 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 col1y col2como cadenas, que probablemente sean ("2016-05-05", etc.) y después de haber leído la cadena, el analizador de fecha de cada columna actuará sobre esa cadena y devolverá lo que devuelva esa función. .

Definición de su propia función de análisis de fecha:

La pandas.read_csv()función también tiene un argumento de palabra clave llamadodate_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, entonces esto es correcto

date_parser = pd.datetools.to_datetime

Esto es incorrecto :

date_parser = pd.datetools.to_datetime()

Pandas 0.22 Actualizar

pd.datetools.to_datetime ha sido reubicado en date_parser = pd.to_datetime

Gracias @stackoverYC

firelynx
fuente
1
@Drake Creo que user3221055 nunca regresó al sitio. Ese es el problema. El perfil dice "Visto por última vez el 20 de mayo de 2014 a las 2:35"
firelynx
2
Esta es una solución lenta. Vea esto en su lugar: stackoverflow.com/questions/29882573/…
user1761806
@ user1761806 ¡Hola, buen hallazgo! Aunque hice uno mejor. stackoverflow.com/a/46183514/3730397
firelynx
2
En pandas 0.22.0 dice que pandas.core.datetools.to_datetimeestá en desuso, use pd.datetools.to_datetimeen su lugar. así:date_parser = pd.to_datetime
stackoverYC
1
También hay un convertersparámetro en el que puede especificar qué columnas tienen qué convertidores. parse_dates es útil y maneja datos incorrectos, pero es más lento debido a que prueba e infiere cada valor gist.github.com/gjreda/7433f5f70299610d9b6b
Davos
31

Existe un parse_datesparámetro para el read_csvque le permite definir los nombres de las columnas que desea tratar como fechas o fechas y horas:

date_cols = ['col1', 'col2']
pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=date_cols)
mrjrdnthms
fuente
Tenía un error cuando pasaba el nombre de una sola cadena de la columna, ahora entiendo que también necesitaba pasar la lista para un solo valor.
TapanHP
15

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 ninguno de sus datos para manipular.

Y realmente, probablemente 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)
Paul H
fuente
7

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)

Encontré el siguiente error:

TypeError: data type not understood

El único cambio que tuve que hacer es 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)
José Buraschi
fuente
3
Esto seguirá haciendo que el dtype del marco de datos resultante sea un objeto, no un pandas.datetime
firelynx
11
Aparte del hecho de que esto no tiene el efecto deseado, tampoco funciona:AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
Gabriel