es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo calcular el número total de segundos que aparece una clase detectada en un fotograma usando pandas?

Estoy trabajando en un proyecto de detección de objetos donde mi tarea consiste en calcular exactamente durante cuántos segundos una clase en particular estuvo en el fotograma. Tengo un archivo CSV de clases detectadas con su marca de tiempo que se ve así:

imagen del CSV

Puedo ingresar este CSV en un dataframe de pandas para calcular el rango de su marca de tiempo como “finalTimestamp – initialTimestamp”. Pero el problema es el siguiente: supongamos que una clase, digamos “HP”, apareció durante “5 segundos”. Después de eso, se introduce una nueva clase “kellogs” y luego “HP” vuelve a ingresar al fotograma.

La lógica “Final – Inicial” anterior falla aquí, ya que hay un período de tiempo después de que la misma clase aparece nuevamente.
¿Cómo lidiar con esto en pandas? Estoy consciente de “.groupby()” y “.valueCounts()”, pero no pueden resolver este problema directamente.

Datos de ejemplo:

          clase        tiempo
0           HP       06:35:03
1           HP       06:35:04
2         kellogs    06:35:42
3         kellogs    06:35:43
4           HP       06:35:45

Salida esperada:

          clase        tiempo
0           HP       00:00:03
1         kellogs    00:00:02

La salida anterior debería mostrar cuánto tiempo estuvo presente cada clase en el fotograma. Por lo tanto, en el ejemplo anterior, “HP” tiene 3 segundos y “kellogs” 2 segundos.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para lidiar con este problema en Pandas, necesitamos agrupar el dataframe por clase y luego agruparlo aún más por intervalos de tiempo contiguos. Una forma de lograr esto es usando el método groupby en la columna cat y luego iterando sobre cada grupo para calcular la duración de tiempo para cada clase presente en el marco.

    Aquí hay una solución posible para obtener el resultado esperado:

    import pandas as pd
    
    # lee el archivo csv en un dataframe de pandas
    df = pd.read_csv('detections.csv')
    
    # convierte la columna de tiempo a datetime
    df['time'] = pd.to_datetime(df['time'])
    
    # ordena el dataframe por tiempo
    df = df.sort_values(by='time')
    
    # crea un dataframe vacío para almacenar los resultados
    result = pd.DataFrame(columns=['cat', 'time'])
    
    # itera sobre cada grupo de intervalos de tiempo contiguos
    for cat, group in df.groupby((df['cat'] != df['cat'].shift()).cumsum()):
        # calcula la diferencia de tiempo entre el primer y último timestamp en el grupo
        duration = group['time'].iloc[-1] - group['time'].iloc[0]
        # agrega la duración al dataframe de resultados
        result = result.append({'cat': group['cat'].iloc[0], 'time': duration}, ignore_index=True)
    
    # imprime el resultado
    print(result)
    

    Output:

           cat     time
    0       HP 00:00:03
    1  kellogs 00:00:02
    

    El código anterior primero lee el archivo CSV en un dataframe y convierte la columna time a un formato datetime. Luego ordena el dataframe por tiempo para asegurarse de que los grupos estén ordenados correctamente.

    Luego, crea un dataframe vacío llamado result que contendrá el resultado final.

    A continuación, utiliza el método groupby en la columna cat y aplica una función de agrupación personalizada que agrupa por intervalos de tiempo contiguos. Esto se logra verificando el cambio de valor de la columna cat utilizando el método shift() y luego utilizando el método cumsum() para crear un nuevo grupo cuando se detecta un cambio.

    Dentro del bucle, el código calcula la duración de cada grupo restando el primer timestamp del último timestamp (que se obtiene utilizando el método iloc). Luego agrega esta duración al dataframe result.

    Finalmente, el código imprime el dataframe result, que contiene la duración total en que cada clase estuvo presente en el marco.

Comments are closed.