Python v-stacking 循环

Python v-stacking in a loop

我正在看这个计算机视觉中的一个例子 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 数组非常效率低下。串联总是会生成一个副本,随着您的数组在循环中变得越来越大,它变得越来越昂贵。

相反,做以下两件事之一:

  1. 正如您所做的那样,将中间值存储在常规 Python list 中,并将其转换为循环外的 numpy 数组。附加到 listO(1),而连接 np.ndarrays 是 O(n+k)

  2. 如果你提前知道最终数组有多大,你可以预先分配它,然后在你的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 to lazily generate the array from an iterable object, for example in .