使用python创建一个时间列表中的平均值

时间:2012-08-20 07:42:22

标签: python

我有很多次(HH:MM:SS),我知道如果我想创建一个平均值,我可以将小时,秒和分钟分开并平均每个,然后将它们连接在一起。但是我觉得必须有更好的方法来做到这一点。有谁知道更好的方法吗?

谢谢!

7 个答案:

答案 0 :(得分:5)

这是@eumiro回答的一个可能的实现,但是这个逻辑只有在持续时间有效时才有效,而不是@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))))
@SilentGhost的{p> Also thanks to a post,@ Herms的and a post

答案 1 :(得分:4)

您不希望以这种方式在小时,分钟和秒上“平均”次数:

00:59:00
01:01:00

平均显示为01:00:00,但与您提供的逻辑无关。

而是将所有时间间隔转换为秒,计算平均值并转换回HH:MM:SS

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

答案 2 :(得分:3)

自午夜转换为秒并进行平均时出现问题。如果你在23:50和00:10这样做,你得到的时间是00:00 00:00。

更好的方法是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)

答案 3 :(得分:2)

首先使用strptime从字符串格式到时间结构解析时间,然后使用mktime将时间从纪元转换为秒,然后你应该添加所有秒并除以次数,并使用localtime

转换回时间结构

以下是一个例子:

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)

请注意,我添加了2000年,因为mktime为默认年份1900提供了OverflowError

答案 4 :(得分:1)

我认为最好的办法是将所有这些值转换为秒数并平均整个列表。我假设这些时间是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)

这基本上是eumiro推荐的。第一行计算每个字符串的秒数。第二行平均值。接下来的两行显示秒数/分钟/小时数,第三行很好地格式化输出。

答案 5 :(得分:1)

您需要将其转换为复合体,接受参数,然后平均度数。

最后,您将不需要解析日期以获取所需的内容,然后转换回原始时间。

transform

答案 6 :(得分:0)

对于已经做出的出色答案,可能有一种替代方法,但这是针对特定情况的。例如,如果您希望平均每天上床睡觉的时间(通常是下午6点至早上6点之间的时间),则可以先将小时和分钟转换为十进制,这样12:30 = 12.5 ,此后,您只需要在估算平均值的时间范围内加上24。对于睡眠情况,将花费0:00和6:00 AM之间的时间,变成24.0和30。现在您可以像平常一样估算平均值。最后,如果平均值大于24,则只需再减去24,就可以了:

def hourtoDec(data):
    '''
    Transforms the hour string values in the list data
    to decimal. The format assumed is HH:mm.
    Values are transformed to float
    For example for 5:30pm the equivalent is 17.5 
    This funtion preserves NaN values
    '''
    dataOutput=[]
    for i in data:
        if not(pd.isnull(i)):
            if type(i)==type("a"):
                    h,m=i.split(':')
                    h=int(h)
                    m=int(m)
                    dataOutput.append(h+m/60.0)
            if isinstance(i, (np.float, float)):
                    dataOutput.append(i)
        else:
            dataOutput.append(i)
    return dataOutput



timestr=pd.DataFrame([ "2020-04-26T23:00:30.000", 
                      "2020-04-25T22:00:30.000", 
                      "2020-04-24T01:00:30.000", 
                      "2020-04-23T02:00:30.000"],columns=["timestamp"])
hours=timestr['timestamp'].apply(lambda x: ":".join(x.split("T")[1].split(":")[0:2]))
hoursDec=hourtoDec(hours)

times2=[]
for i in hoursDec:
    if i>=0 and i<6:
        times2.append(i+24)
    else:
        times2.append(i)

average=np.mean(times2)
if average>=24:
    average=average-24
print(average)