Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

como trabalhar com voltas de corridas m:ss.milesimos

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

8 respostas

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.

solução!

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:

VoltaTempoT1T2T3T4seilacarropitcategoria
0295483.027324.029755.020304.018098.01681101
1381994.021065.025901.018780.016247.0234,81101
2475882.018619.024097.017156.016009.0256,51101
3580412.018411.023827.021186.016986.0256,51101
4679806.018416.024304.020407.016678.0256,51101

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+ :)