我有两段代码(执行相同的工作),它接受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)
如何改进第一段代码以使其快速运行?
答案 0 :(得分:1)
根据尺寸,您会看到巨大的list
元素,即巨大的len
。你的第二个代码只有一个for
循环,因为你的第一个方法有很多。你看到一个对吗?它们的格式为map()
,groupby()
。巨大的列表上的多次迭代正在增加时间复杂性的巨大成本。 这些不仅仅是额外的迭代,而且还比普通的for
循环慢。
我对另一篇您认为有用Comparing list comprehensions and explicit loops的帖子进行了比较。
此外,使用lambda
功能会增加额外的时间。
但是,您可以通过将results.append
存储到单独的变量my_func
并将其作为my_func(current_group)
进行调用来进一步缩短代码的执行时间。
几乎没有比较: