tipos de data e hora em pandas read_csv

126

Estou lendo em um arquivo csv com várias colunas datetime. Eu precisaria definir os tipos de dados após a leitura no arquivo, mas às vezes parece ser um problema. Por exemplo:

headers = ['col1', 'col2', 'col3', 'col4']
dtypes = ['datetime', 'datetime', 'str', 'float']
pd.read_csv(file, sep='\t', header=None, names=headers, dtype=dtypes)

Quando a execução dá um erro:

TypeError: tipo de dados "datetime" não entendido

A conversão de colunas após o fato, via pandas.to_datetime (), não é uma opção. Não sei quais colunas serão objetos de data e hora. Essa informação pode mudar e vem de tudo o que informa minha lista de tipos.

Como alternativa, tentei carregar o arquivo csv com numpy.genfromtxt, definir os dtypes nessa função e depois converter em um pandas.dataframe, mas ele confunde os dados. Qualquer ajuda é muito apreciada!

user3221055
fonte

Respostas:

272

Por que não funciona

Não há nenhum tipo de data / hora para definir para read_csv, pois os arquivos csv podem conter apenas cadeias, números inteiros e flutuantes.

Definir um dtype como datetime fará com que os pandas interpretem o datetime como um objeto, o que significa que você terminará com uma string.

Pandas maneira de resolver isso

A pandas.read_csv()função possui um argumento de palavra-chave chamadoparse_dates

Com isso, você pode rapidamente converter seqüências, flutuadores ou números inteiros em data e hora usando o padrão 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)

Isso fará com que os pandas leiam col1e col2como strings, o que eles provavelmente são ("05-05-2016" etc.) e depois de ler a string, o date_parser de cada coluna atuará nessa string e devolverá o que a função retornar .

Definindo sua própria função de análise de data:

A pandas.read_csv()função também possui um argumento de palavra-chave chamadodate_parser

Definir isso para uma função lambda fará com que essa função específica seja usada para a análise das datas.

AVISO DE GOTCHA

Você precisa atribuir a função, não a execução da função, portanto, isso é Correto

date_parser = pd.datetools.to_datetime

Isso está incorreto :

date_parser = pd.datetools.to_datetime()

Pandas 0.22 Atualizar

pd.datetools.to_datetime foi realocado para date_parser = pd.to_datetime

Obrigado @stackoverYC

firelynx
fonte
1
@ Drake Acho que o user3221055 nunca voltou ao site. Esse é o problema. O perfil diz "Visto pela última vez em 20 de maio de '14 às 2:35"
firelynx
2
Esta é uma solução lenta. Veja isso: stackoverflow.com/questions/29882573/…
user1761806
@ user1761806 Ei, boa localização! Eu fiz um melhor embora. stackoverflow.com/a/46183514/3730397
firelynx 12/12
2
Nos pandas 0.22.0 diz que pandas.core.datetools.to_datetimeestá obsoleto, use em seu pd.datetools.to_datetimelugar. assim:date_parser = pd.to_datetime
stackoverYC
1
Há também um convertersparâmetro em que você pode especificar quais colunas têm quais conversores. parse_dates é útil e os dados alças ruim, mas é mais lento devido a testar e inferir cada valor gist.github.com/gjreda/7433f5f70299610d9b6b
Davos
31

Há um parse_datesparâmetro para o read_csvqual permite definir os nomes das colunas que você deseja tratar como datas ou horários:

date_cols = ['col1', 'col2']
pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=date_cols)
mrjrdnthms
fonte
Eu estava tendo um erro ao passar o nome de uma única string da coluna, agora entendo que também precisava passar na lista por um único valor.
TapanHP
15

Você pode tentar passar tipos reais em vez de cadeias.

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)

Mas será realmente difícil diagnosticar isso sem que nenhum dos seus dados seja mexido.

E, realmente, você provavelmente deseja que os pandas analisem as datas no TimeStamps, para que possa ser:

pd.read_csv(file, sep='\t', header=None, names=headers, parse_dates=True)
Paul H
fonte
7

Eu tentei usar a opção dtypes = [datetime, ...], mas

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)

Eu encontrei o seguinte erro:

TypeError: data type not understood

A única alteração que tive que fazer é substituir datetime por 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)
Jose Buraschi
fonte
3
Isso ainda vai fazer a dtipo da resultando trama de dados de um objeto, não um pandas.datetime
firelynx
11
Além do fato de que isso não tem o efeito desejado, ele também não funciona:AttributeError: type object 'datetime.datetime' has no attribute 'datetime'
Gabriel