Boa tarde. Gostaria de saber como eu faço o pandas interpretar tempo de volta de corrida. Quando eu uso por exemplo o describe() não mostra os tempos das voltas.
Exemplo de tempo de volta: 1:35.483
Sendo minuto:segundos.milesimosdeseg
Boa tarde. Gostaria de saber como eu faço o pandas interpretar tempo de volta de corrida. Quando eu uso por exemplo o describe() não mostra os tempos das voltas.
Exemplo de tempo de volta: 1:35.483
Sendo minuto:segundos.milesimosdeseg
Olá Luiz,
Compartilha o código e os dados se possível pra gente entender melhor o cenário.
dados.head()
Volta Tempo T1 T2 T3 T4 seila carro pit categoria
0 2 1:35.483 27.324 29.755 20.304 18.098 168 11 0 1
1 3 1:21.994 21.065 25.901 18.780 16.247 234,8 11 0 1
2 4 1:15.882 18.619 24.097 17.156 16.009 256,5 11 0 1
3 5 1:20.412 18.411 23.827 21.186 16.986 256,5 11 0 1
4 6 1:19.806 18.416 24.304 20.407 16.678 256,5 11 0 1
dados.describe().round(2)
Volta T1 carro pit categoria
count 215.00 215.00 215.00 215.00 215.00
mean 12.50 21.55 44.13 0.16 1.29
std 7.18 3.97 49.15 0.37 0.45
min 2.00 17.84 5.00 0.00 1.00
25% 6.00 18.70 9.00 0.00 1.00
50% 12.00 19.86 20.00 0.00 1.00
75% 18.00 23.50 65.00 0.00 2.00
max 33.00 36.70 175.00 1.00 2.00
Tipo eu nao sei pq agora no describe nao aparece "tempo", "t2", "t3", "t4", "seila". Eu acredito que tem relação com ter minutos, pq "t1" é a unica tomada de tempo q não chega a dar um minuto.
Parece ser algo relacionado ao tipo dos seus dados, o resultado do describe
varia de acordo com o tipo de cada coluna, nesse seu exemplo parece que as colunas abaixo são as únicas reconhecidas como números, e por isso aparecem no describe apenas:
Volta | T1 | carro | pit | categoria
Você pode ver o tipo de cada coluna executando: dados.dtypes
Recomendo você utilizar apenas milisegundos em todas as colunas de tempo, ou converter essas colunas para o tipo datetime
ou timedelta
.
Vou procurar algumas formas de fazer a conversão dos seus dados para os tipos que eu falei acima e posto aqui.
Para fazer a conversão é um pouco complicado caso o formato dos dados tenha alguma variação.
Conversão para datetime
Para valores com apenas segundos e milissegundos no formato 00.000
você pode converter assim:
df['T1'] = pd.to_datetime(df['T1'].astype('object'), format='%S.%f')
df['T2'] = pd.to_datetime(df['T2'].astype('object'), format='%S.%f')
df['T3'] = pd.to_datetime(df['T3'].astype('object'), format='%S.%f')
df['T4'] = pd.to_datetime(df['T4'].astype('object'), format='%S.%f')
Já para a coluna tempo que tem o formato 00:00.000
pode ser algo assim:
df['Tempo'] = pd.to_datetime(df['Tempo'], format='%M:%S.%f')
Conversão para timedelta
O tipo timedelta
é o mais recomendado para utilizar no seu caso (junto de utilizar apenas milissegundos).
Continuando direto da conversão acima você pode fazer assim:
df['Tempo'] = pd.to_timedelta(df['Tempo'].dt.strftime('%H:%M:%S.%f'))
df['T1'] = pd.to_timedelta(df['T1'].dt.strftime('%H:%M:%S.%f'))
df['T2'] = pd.to_timedelta(df['T2'].dt.strftime('%H:%M:%S.%f'))
df['T3'] = pd.to_timedelta(df['T3'].dt.strftime('%H:%M:%S.%f'))
df['T4'] = pd.to_timedelta(df['T4'].dt.strftime('%H:%M:%S.%f'))
Conversão para milissegundos
Com essa última conversão você vai ter números do tipo float em uma única unidade: milissegundos (ms)
Continuando novamente direto da conversão acima você pode fazer assim para obter os valores em ms
:
df['Tempo'] = df['Tempo'] / np.timedelta64(1, 'ms')
df['T1'] = df['T1'] / np.timedelta64(1, 'ms')
df['T2'] = df['T2'] / np.timedelta64(1, 'ms')
df['T3'] = df['T3'] / np.timedelta64(1, 'ms')
df['T4'] = df['T4'] / np.timedelta64(1, 'ms')
No final você vai ter sua tabela assim:
Volta | Tempo | T1 | T2 | T3 | T4 | seila | carro | pit | categoria | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 2 | 95483.0 | 27324.0 | 29755.0 | 20304.0 | 18098.0 | 168 | 11 | 0 | 1 |
1 | 3 | 81994.0 | 21065.0 | 25901.0 | 18780.0 | 16247.0 | 234,8 | 11 | 0 | 1 |
2 | 4 | 75882.0 | 18619.0 | 24097.0 | 17156.0 | 16009.0 | 256,5 | 11 | 0 | 1 |
3 | 5 | 80412.0 | 18411.0 | 23827.0 | 21186.0 | 16986.0 | 256,5 | 11 | 0 | 1 |
4 | 6 | 79806.0 | 18416.0 | 24304.0 | 20407.0 | 16678.0 | 256,5 | 11 | 0 | 1 |
E o describe
vai incluir os valores de tempo.
Ficou um pouco grande a resposta então não entrei em detalhes sobre cada conversão, mas qualquer dúvida pode perguntar.
agora deu esse erro:(
isso para 'T2', mas ocorre a coisas parecidas para 'T3' e 'T4'.
time data '2:09.676' does not match format '%S.%f' (match)
Para fazer a conversão é um pouco complicado caso o formato dos dados tenha alguma variação.
Pelo jeito o formato varia, mas com uns passos a mais dá pra resolver. Novamente eu vou preparar um código de exemplo e te mando.
Para explicar melhor, em df['T1'] = pd.to_datetime(df['T1'].astype('object'), format='%S.%f')
estamos passando o format
indicando que os valores estão no padrão 00.000
, o que não é verdade para todos os valores.
Para evitar isso podemos adicionar 00:
em todos os valores, para obter o seguinte resultado:
# Exemplo
22.324 é transformado em 00:22.324
2:09.676 é transformado em 00:2:09.676
Com os valores assim podemos mandar o format procurar os valores sem esperar um resultado exato, utilizando o parâmetro exact=False
Código completo (remova o que foi feito nos códigos que mandei acima):
# imports
import pandas as pd
import numpy as np
from datetime import datetime
# Criação do DataFrame de teste
columns = ['Volta', 'Tempo', 'T1', 'T2', 'T3', 'T4', 'seila', 'carro', 'pit', 'categoria']
data = [
[2, '1:35.483', 27.324, '1:29.755', '20.304', '18.098', '168', '11', '0', '1'],
[3, '1:21.994', 21.065, '1:25.901', '18.780', '16.247', '234,8', '11', '0', '1'],
[4, '1:15.882', 18.619, '24.097', '17.156', '16.009', '256,5', '11', '0', '2'],
[5, '1:20.412', 18.411, '2:23.827', '21.186', '16.986', '256,5', '12', '0', '1'],
[6, '1:19.806', 18.416, '24.304', '20.407', '16.678', '256,5', '12', '0', '2']
]
df = pd.DataFrame(data=data, columns=columns)
# Função para adicionar o 00:
def formata_tempo(linha):
return '00:' + str(linha)
# Conversão para datetime
df['Tempo'] = pd.to_datetime(df['Tempo'].apply(formata_tempo), format='%M:%S.%f', exact=False)
df['T1'] = pd.to_datetime(df['T1'].apply(formata_tempo), format='%M:%S.%f', exact=False)
df['T2'] = pd.to_datetime(df['T2'].apply(formata_tempo), format='%M:%S.%f', exact=False)
df['T3'] = pd.to_datetime(df['T3'].apply(formata_tempo), format='%M:%S.%f', exact=False)
df['T4'] = pd.to_datetime(df['T4'].apply(formata_tempo), format='%M:%S.%f', exact=False)
# Conversão para timedelta
df['Tempo'] = pd.to_timedelta(df['Tempo'].dt.strftime('%H:%M:%S.%f'))
df['T1'] = pd.to_timedelta(df['T1'].dt.strftime('%H:%M:%S.%f'))
df['T2'] = pd.to_timedelta(df['T2'].dt.strftime('%H:%M:%S.%f'))
df['T3'] = pd.to_timedelta(df['T3'].dt.strftime('%H:%M:%S.%f'))
df['T4'] = pd.to_timedelta(df['T4'].dt.strftime('%H:%M:%S.%f'))
# Conversão para milissegundos
df['Tempo'] = df['Tempo'] / np.timedelta64(1, 'ms')
df['T1'] = df['T1'] / np.timedelta64(1, 'ms')
df['T2'] = df['T2'] / np.timedelta64(1, 'ms')
df['T3'] = df['T3'] / np.timedelta64(1, 'ms')
df['T4'] = df['T4'] / np.timedelta64(1, 'ms')
Lembrando que caso exista mais diferenças no formato dos dados ainda pode falhar.
Cara vc é d+ :)