加速不使用groupby()的代码?

时间:2016-10-07 10:49:48

标签: python lambda

我有两段代码(执行相同的工作),它接受datetime数组并生成datetime的集群,这些集群的差异为1小时。

第一件是:

def findClustersOfRuns(data):
    runClusters = []
    for k, g in groupby(itertools.izip(data[0:-1], data[1:]),
                        lambda (i, x): (i - x).total_seconds() / 3600):
        runClusters.append(map(itemgetter(1), g))

第二部分是:

def findClustersOfRuns(data):
    if len(data) <= 1:
        return []
        current_group = [data[0]]
        delta = 3600
        results = []

        for current, next in itertools.izip(data, data[1:]):
            if abs((next - current).total_seconds()) > delta:
                # Here, `current` is the last item of the previous subsequence
                # and `next` is the first item of the next subsequence.
                if len(current_group) >= 2:
                    results.append(current_group)

                current_group = [next]
                continue

            current_group.append(next)

        return results

第一段代码需要5分钟才能执行,而第二段需要几秒钟。我想了解原因。

我运行代码的数据有大小:

data.shape
(13989L,)

数据内容如下:

data
array([datetime.datetime(2016, 10, 1, 8, 0),
       datetime.datetime(2016, 10, 1, 9, 0),
       datetime.datetime(2016, 10, 1, 10, 0), ...,
       datetime.datetime(2019, 1, 3, 9, 0),
       datetime.datetime(2019, 1, 3, 10, 0),
       datetime.datetime(2019, 1, 3, 11, 0)], dtype=object)

如何改进第一段代码以使其快速运行?

1 个答案:

答案 0 :(得分:1)

根据尺寸,您会看到巨大的list元素,即巨大的len。你的第二个代码只有一个for循环,因为你的第一个方法有很多。你看到一个对吗?它们的格式为map()groupby()。巨大的列表上的多次迭代正在增加时间复杂性的巨大成本。 这些不仅仅是额外的迭代,而且还比普通的for循环慢。

我对另一篇您认为有用Comparing list comprehensions and explicit loops的帖子进行了比较。

此外,使用lambda功能会增加额外的时间。

但是,您可以通过将results.append存储到单独的变量my_func并将其作为my_func(current_group)进行调用来进一步缩短代码的执行时间。

几乎没有比较: