Usando Python para crear un promedio de una lista de veces

Tengo una gran lista de veces (HH: MM: SS) y sé que si quisiera crear un promedio, podría separar las Horas, Segundos y Minutos y promediar cada una y luego concatenarlas de nuevo. Sin embargo, siento que debe haber una mejor manera de hacerlo. ¿Alguien sabe de una mejor manera de hacer esto?

¡Gracias!

No quiere “promediar” los tiempos en horas, minutos y segundos de esta manera:

 00:59:00 01:01:00 

01:00:00 claramente a 01:00:00 , pero no con la lógica que presentó.

En su lugar, convierta todos sus intervalos de tiempo en segundos, calcule el promedio y vuelva a convertir a HH:MM:SS .

 00:59:00 -> 3540 seconds 01:01:00 -> 3660 seconds ============ average: 3600 seconds converted to HH:MM:SS -> 01:00:00 

Aquí hay una posible implementación de la respuesta por @eumiro, pero esta lógica solo funciona si son duraciones, no tiempos, como lo señala @lazyr:

 from datetime import timedelta times = ['00:58:00','00:59:00','01:00:00','01:01:00','01:02:00'] print(str(timedelta(seconds=sum(map(lambda f: int(f[0])*3600 + int(f[1])*60 + int(f[2]), map(lambda f: f.split(':'), times)))/len(times)))) 

También gracias a una publicación de @SilentGhost, y una publicación de @Herms

Primero analice el tiempo desde el formato de cadena a la estructura de tiempo usando strptime , luego convierta el tiempo a segundos de la época usando mktime , luego debe agregar todos los segundos y dividir por el número de veces, y para volver a la estructura de tiempo usando localtime

Aquí hay un ejemplo:

 import time a = time.strptime("2000:11:12:13","%Y:%H:%M:%S") b = time.strptime("2000:11:14:13","%Y:%H:%M:%S") avg_time = time.localtime(((time.mktime(a)+time.mktime(b))/2)) >> time.struct_time(tm_year=2000, tm_mon=1, tm_mday=1, tm_hour=11, tm_min=13, tm_sec=13, tm_wday=5, tm_yday=1, tm_isdst=0) 

Tenga en cuenta que agregué el año 2000 porque mktime da OverflowError para el año predeterminado 1900

Hay un problema con la conversión a segundos desde la medianoche y el promedio. Si haces eso con 23:50 y 00:10 obtienes 12:00 cuando lo quieres 00:00.

Un mejor enfoque es promediar los angularjs .

 import datetime import math import numpy def datetime_to_radians(x): # radians are calculated using a 24-hour circle, not 12-hour, starting at north and moving clockwise time_of_day = x.time() seconds_from_midnight = 3600 * time_of_day.hour + 60 * time_of_day.minute + time_of_day.second radians = float(seconds_from_midnight) / float(12 * 60 * 60) * 2.0 * math.pi return radians def average_angle(angles): # angles measured in radians x_sum = numpy.sum([math.sin(x) for x in angles]) y_sum = numpy.sum([math.cos(x) for x in angles]) x_mean = x_sum / float(len(angles)) y_mean = y_sum / float(len(angles)) return numpy.arctan2(x_mean, y_mean) def radians_to_time_of_day(x): # radians are measured clockwise from north and represent time in a 24-hour circle seconds_from_midnight = int(float(x) / (2.0 * math.pi) * 12.0 * 60.0 * 60.0) hour = seconds_from_midnight / 3600 minute = (seconds_from_midnight % 3600) / 60 second = seconds_from_midnight % 60 return datetime.time(hour, minute, second) def average_times_of_day(x): # input datetime.datetime array and output datetime.time value angles = [datetime_to_radians(y) for y in x] avg_angle = average_angle(angles) return radians_to_time_of_day(avg_angle) average_times_of_day([datetime.datetime(2017, 6, 9, 0, 10), datetime.datetime(2017, 6, 9, 0, 20)]) # datetime.time(0, 15) average_times_of_day([datetime.datetime(2017, 6, 9, 23, 50), datetime.datetime(2017, 6, 9, 0, 10)]) # datetime.time(0, 0) 

Creo que lo mejor es convertir todos esos valores en una cantidad de segundos y promediar toda la lista. mylist que estos tiempos son cadenas en mylist .

  time_list = map(lambda s: int(s[6:8]) + 60*(int(s[3:5]) + 60*int(s[0:2])), mylist) average = sum(time_list)/len(time_list) bigmins, secs = divmod(average, 60) hours, mins = divmod(bigmins, 60) print "%02d:%02d:%02d" % (hours, mins, secs) 

Esto es esencialmente lo que recomienda eumiro. La primera línea calcula el número de segundos para cada cadena. La segunda línea los promedia. Las siguientes dos líneas calculan la cantidad de segundos / minutos / horas, y la tercera línea formatea muy bien la salida.

Necesita convertirlo en complejo, tomar el argumento y luego promediar los grados.

Finalmente, deberá analizar la fecha para obtener lo que desea y luego volver a la hora original.

 from cmath import rect, phase from math import radians, degrees def meanAngle(deg): complexDegree = sum(rect(1, radians(d)) for d in deg) / len(deg) argument = phase(complexDegree) meanAngle = degrees(argument) return meanAngle def meanTime(times): t = (time.split(':') for time in times) seconds = ((float(s) + int(m) * 60 + int(h) * 3600) for h, m, s in t) day = 24 * 60 * 60 toAngles = [s * 360. / day for s in seconds] meanAsAngle = meanAngle(toAngles) meanSeconds = meanAsAngle * day / 360. if meanSeconds < 0: meanSeconds += day h, m = divmod(meanSeconds, 3600) m, s = divmod(m, 60) return('%02i:%02i:%02i' % (h, m, s)) print(meanTime(["15:00:00", "21:00:00"])) # 18:00:00 print(meanTime(["23:00:00", "01:00:00"])) # 00:00:00