Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using python to create an average out of a list of times

Tags:

python

I have a huge list of times (HH:MM:SS) and I know that if I wanted to create an average I could separate the Hours, Seconds, and Minutes and average each one and then concatenate them back together. However I feel that there must be a better way to do that. Does anyone know of a better way to do this?

Thanks!

like image 937
TheBeardedBerry Avatar asked Aug 20 '12 07:08

TheBeardedBerry


People also ask

How do you find the average of a list of times?

The formula to calculate average is done by calculating the sum of the numbers in the list divided by the count of numbers in the list.

How do you get an average from a list Python?

To find the average of given numbers in a list, we use the Python Average function. Average in Python is usually calculated by adding all the numbers in a list and then dividing it by the number of elements in this list.

How do you find the average of time in Python?

In Python we can find the average of a list by simply using the sum() and len() function. sum() : Using sum() function we can get the sum of the list.


2 Answers

There's a problem with converting to seconds since midnight and averaging. If you do that with 23:50 and 00:10 you get 12:00 when what you want it 00:00.

A better approach is to average the angles.

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)
like image 186
polimath Avatar answered Oct 06 '22 00:10

polimath


You don't want to "average" times on hours, minutes and seconds this way:

00:59:00
01:01:00

average clearly to 01:00:00, but not with the logic you presented.

Instead convert all your time intervals into seconds, calculate the average and convert back to HH:MM:SS.

00:59:00 -> 3540 seconds
01:01:00 -> 3660 seconds
            ============
average:    3600 seconds converted to HH:MM:SS -> 01:00:00
like image 25
eumiro Avatar answered Oct 05 '22 23:10

eumiro