计算字典中所有时间差值的总和

3
我有一个包含时间差值的字典。
{1: Timedelta('0 days 01:44:39'),
 2: Timedelta('0 days 02:34:01'),
 3: Timedelta('0 days 00:49:15'),
 4: Timedelta('0 days 01:13:26'),
 5: Timedelta('0 days 00:38:14')}

我想总结所有值并显示一个时间戳总和(所有时间戳相加)作为输出。有什么方法可以实现这个要求吗?我尝试将其转换为列表,然后使用sum()函数,但它们不能与时间戳一起使用。
3个回答

2

sum(iterable, start)
iterable :迭代器可以是任何东西,如列表、元组或字典,但最重要的是应该是数字。

start :将此 start 添加到可迭代的数字总和中。

从上面可以看出,sum 函数仅适用于 numbers

要使其适用于 timedeltas,请使用 Python 的 datetime 模块。 执行以下操作:

In [804]: d = {1: Timedelta('0 days 01:44:39'),
     ...:  2: Timedelta('0 days 02:34:01'),
     ...:  3: Timedelta('0 days 00:49:15'),
     ...:  4: Timedelta('0 days 01:13:26'),
     ...:  5: Timedelta('0 days 00:38:14')}

In [805]: import datetime

In [803]: sum(d.values(), datetime.timedelta())
Out[803]: Timedelta('0 days 06:59:35')

小数据集所有答案的时间性能:

@jezrael 的答案:

In [806]: def j():
     ...:     s = pd.Series(d)
     ...:     return s.sum()
     ...: 

In [807]: %timeit j()
491 µs ± 86.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

@Pablo的回答:
In [810]: %timeit reduce(lambda a,b: a+b, d.values())
22.7 µs ± 250 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

@我的回答:

In [808]: %timeit sum(d.values(), datetime.timedelta())
31.9 µs ± 451 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

2
@JSVJ已经发布了所有答案的一些时间表现。其中Series答案表现最差。 - Mayank Porwal
1
@MayankPorwal - 你能为1k、10k行添加性能吗? - jezrael
2
Pandas在对行求和时表现并不差,但相对而言创建Series的开销较大。要么将其从基准测试中排除,要么使用更多的行,这样Pandas的速度会快得多。 - JulianWgs
@JulianWgs - 嗨,我认为这里的问题在于只比较了少数值。同时,比较删除缺失值后再看差异,pandas胜出。 - jezrael
1
是的,当行数很多时,pandas可能会胜出。让我们等待OP回来,看他正在处理什么类型的数据集。我猜对于小型数据集来说,使用pandas并不是最好的选择。 - Mayank Porwal
显示剩余4条评论

1
将字典转换为Series,因此可以使用默认情况下排除NoneNaN的时间增量的sum
d = {1: pd.Timedelta('0 days 01:44:39'),
 2: pd.Timedelta('0 days 02:34:01'),
 3: pd.Timedelta('0 days 00:49:15'),
 4: pd.Timedelta('0 days 01:13:26'),
 5: pd.Timedelta('0 days 00:38:14')}

s = pd.Series(d)
print (s.sum())
0 days 06:59:35

哦,我的天啊。非常感谢。我学到了很多。 - JSVJ

1
你可以使用 functools.reduce
>>> from functools import reduce
>>> d = {1: pd.Timedelta('0 days 01:44:39'),
 2: pd.Timedelta('0 days 02:34:01'),
 3: pd.Timedelta('0 days 00:49:15'),
 4: pd.Timedelta('0 days 01:13:26'),
 5: pd.Timedelta('0 days 00:38:14')}
>>> reduce(lambda a,b: a+b, d.values())
#Timedelta('0 days 06:59:35')

2
Reduce不被前Python BDFL Guido van Rossum推荐,我也不是它的粉丝。它几乎总是可以通过列表推导式或小循环来避免使用。 - JulianWgs
2
@JulianWgs 我明白在非平凡情况下这是不推荐的,但这里并非如此。 - Pablo C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接