为何datetime.timedelta列表的平均值大于提取微秒值计算的平均值?
timedelta直接求平均与提取微秒求平均结果差异的原因
问题现象
生成一组datetime.timedelta类型的时间差列表,直接计算该列表的平均值,结果比提取每个时间差的微秒值转换为秒后计算的平均值更大,代码及输出如下:
import datetime import time import numpy as np l = [] l_m = [] for _ in range(5): start = datetime.datetime.now() time.sleep(1) l.append((datetime.datetime.now() - start)) l_m.append((datetime.datetime.now() - start).microseconds / 1000000) print(l) print(np.mean(l), np.mean(l_m))
运行输出:
[datetime.timedelta(seconds=1, microseconds=846), datetime.timedelta(seconds=1, microseconds=1017), datetime.timedelta(seconds=1, microseconds=1010), datetime.timedelta(seconds=1, microseconds=1013), datetime.timedelta(seconds=1, microseconds=887)] 0:00:01.000955 0.9639999999999999
核心原因
1. 两次计算时间差的时间点不一致
循环中,加入列表l的时间差是第一次调用datetime.datetime.now()与start的差值,此时刚执行完time.sleep(1),时间差约为1秒+几百微秒;而加入列表l_m的时间差是第二次调用datetime.datetime.now()与start的差值,此时已经完成了一次append操作,距离start的时间更长(实际约1.96秒左右)。
2. 错误使用timedelta.microseconds属性
timedelta.microseconds仅返回时间差中小于1秒的微秒部分(取值范围0-999999),不包含整秒数。例如一个1秒963999微秒的timedelta对象,它的.microseconds值是963999,除以1000000后得到0.963999,但实际总秒数是1.963999。你只提取了微秒部分,相当于丢弃了整秒数,导致计算的数值远小于真实时间差。
修正方案
复用同一个时间差对象,并使用total_seconds()方法获取完整的总秒数:
import datetime import time import numpy as np l = [] l_m = [] for _ in range(5): start = datetime.datetime.now() time.sleep(1) td = datetime.datetime.now() - start # 只计算一次时间差 l.append(td) l_m.append(td.total_seconds()) # 使用total_seconds()获取总秒数 print(l) print(np.mean(l), np.mean(l_m))
修正后,两次计算的平均值会基本一致(例如输出0:00:01.000955和1.000955)。
内容的提问来源于stack exchange,提问作者mherzog
相关产品推荐
相关产品推荐

