首页 > 解决方案 > 将参数传递给 itertools.groupby() 中的键函数以计算键的唯一值

问题描述

我想在特定时间使用两个列表计算某个参数的唯一值的数量 - 一个值和一个时间戳(它们包含不真正相关的毫秒信息,必须转换为秒)。Rn 我有这样的东西

timestamps = ['00:22:33:645', '00:22:33:655', '00:22:34:645','00:22:34:745']
values = [1, 1, 2, 3]

grouped = groupby(zip(values, timestamps), lambda x: timestamp_to_seconds(x[1]))

但它导致

{1353:[(1, '00:22:33:645'), (1, '00:22:33:655')], 1354:[(2, '00:22:34:645'), (3, '00:22:34:745')]}

我宁愿只保留 {1353:[1, 1], 1354:[2, 3]} 这样len(set(group))会给出准确的计数。有没有办法将时间戳传递给关键功能而不将它们放入 zip 中?可以跳过 lambda 吗?

e:添加了实际示例

标签: pythonitertools

解决方案


您必须对 groupby 结果进行后处理。您可以使用defaultdict.

给定

import time
import datetime as dt
import collections as ct


timestamps = ["00:22:33:645", "00:22:33:655", "00:22:34:645","00:22:34:745"]
values = [1, 1, 2, 3]


# Helper
def timestamp_to_seconds(ts: str) -> int:
    """Return an int in total seconds from a timestamp."""
    x = time.strptime(ts.rsplit(":", maxsplit=1)[0],"%H:%M:%S")
    res = dt.timedelta(hours=x.tm_hour, minutes=x.tm_min, seconds=x.tm_sec).total_seconds()
    return int(res)

代码

def regroup(tstamps: list, vals: list) -> dict:
    """Return a dict of seconds-value pairs."""
    dd = ct.defaultdict(list)

    for t, v in zip(tstamps, vals):        
        dd[timestamp_to_seconds(t)].append(v)

    return dict(dd)

演示

regroup(timestamps, values)
# {1353: [1, 1], 1354: [2, 3]}

{k: len(g) for k, g in regroup(timestamps, values).items()}

# {1353: 2, 1354: 2}

另请参阅有关将时间戳转换为秒的帖子。


推荐阅读