我正在查看计算机视觉 book 中的一个示例并对代码感到有点惊讶:
descr = []
descr.append(sift.read_features_from_file(featurefiles[0])[1])
descriptors = descr[0] #stack all features for k-means
for i in arange(1,nbr_images):
descr.append(sift.read_features_from_file(featurefiles[i])[1])
descriptors = vstack((descriptors,descr[i]))
对我来说,这看起来像是一遍又一遍地复制数组,更有效的实现是:
descr = []
descr.append(sift.read_features_from_file(featurefiles[0])[1])
for i in arange(1,nbr_images):
descr.append(sift.read_features_from_file(featurefiles[i])[1])
descriptors = vstack((descr))
或者我在这里遗漏了一些东西并且两个代码不相同。我做了一个小测试:
print("ATTENTION")
print(descriptors.shape)
print("ATTENTION")
print(descriptors[1:10])
列表似乎有所不同?
最佳答案
你说得完全正确 - 在循环内重复连接 numpy 数组极其效率低下。连接总是生成一个副本,随着数组在循环内变得越来越大,副本的成本也越来越高。
相反,请执行以下两项操作之一:
正如您所做的那样,将中间值存储在常规 Python
list
中,并将其转换为循环外的 numpy 数组。追加到列表
是O(1),而连接np.ndarray
是O(n+k)>.如果您提前知道最终数组有多大,则可以预先分配它,然后填充
for
循环中的行,例如:descr = np.empty((nbr_images, nbr_features), dtype=my_dtype) for i in range(nbr_image): descr[i] = sift.read_features_from_file(featurefiles[i])[1]
另一种变体是使用 np.fromiter
从可迭代对象延迟生成数组,例如 this recent question .
关于Python 循环中的 v 堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34026319/