Python 循环中的 v 堆栈

标签 python performance numpy append concatenation

我正在查看计算机视觉 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])

列表似乎有所不同?

enter image description here

最佳答案

你说得完全正确 - 在循环内重复连接 numpy 数组极其效率低下。连接总是生成一个副本,随着数组在循环内变得越来越大,副本的成本也越来越高。

相反,请执行以下两项操作之一:

  1. 正如您所做的那样,将中间值存储在常规 Python list 中,并将其转换为循环外的 numpy 数组。追加到列表O(1),而连接np.ndarrayO(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从可迭代对象延迟生成数组,例如 this recent question .

关于Python 循环中的 v 堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34026319/

相关文章:

python - 如何将 OpenCV 图像提供给 Python 中经过训练的 CNN 模型(添加新维度)?

python - discord.py 类型错误 : unsupported type annotation <class 'discord.interactions.Interaction' >

python - 如何使用 "Min()"创建 SQL Pypika 查询

mysql - 随着我的 mysql 数据库的增长,我有什么选择

python - Tensorflow Dataset API shuffle 将性能降低 9 倍

python - 比较列 pandas python

Python:分割从命令行读取的值的有效方法

python - turtle 删除屏幕上的文字并重写

android - 在 xml 之外应用布局属性有什么缺点?

python - einsum 和 matmul 之间的性能差异