【问题标题】:Get the index of the largest area in a NumPy array获取 NumPy 数组中最大区域的索引
【发布时间】:2020-10-03 18:11:12
【问题描述】:

假设我有以下区域坐标数组[x1, y1, x2, y2]。就我而言,这些坐标描述了图像中检测到的人脸区域:

[
    [1, 1, 41, 41],
    [134, 13, 154, 33]
]

现在,我想获取最大区域或最大区域本身的索引。我知道我可以遍历数组,计算每个条目的面积,然后排序以获得最大的一个。 Python 中的标准循环非常慢,所以我正在寻找一个可以加快处理速度的 NumPy 解决方案(假设该数组中有 1MM 个单独的区域)。

在上面的示例中,我希望获得数组索引 0 或区域本身 [1, 1, 41, 41],因为它是两者中最大的(就面积而言,不是坐标本身最大)。

【问题讨论】:

  • 这是简单的数组算法就足够的情况吗?这足以为您的示例中的每个项目计算一个面积为(a[2]-a[0]) * (a[3]-a[1]),然后找到最大项目的索引。由于我们使用的是numpy,因此不需要迭代。
  • 请不要在没有解释的情况下投反对票。很乐意解决您的问题。

标签: python numpy


【解决方案1】:

不确定内存的限制,但如果将numpynumexpr 结合使用,则在 >1 小时的计算时间内可能会达到 1MM。当算术简单时,numexpr 是一个不错的选择。我对这些选项进行了试验,发现max 方法在 numpy 上最快,但在numexpr 上算术更快:

import numpy as np
import numexpr as ne
a = np.random.randint(10000000, size=(100000000, 4))
a[:,2] = a[:,0]+a[:,2]
a[:,3] = a[:,1]+a[:,3]
x,y,z,t = a[:,0], a[:,1], a[:,2], a[:,3]
%timeit np.max((z-x) * (t-y)) 
%timeit ne.evaluate('max((z-x) * (t-y))')
%timeit np.max(ne.evaluate('(z-x) * (t-y)'))

输出:

1.04 s ± 11.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
701 ms ± 2.68 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
330 ms ± 2.35 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

相比之下,max 项目的索引可以这样找到:

%timeit np.argmax((z-x) * (t-y)) 
%timeit np.argmax(ne.evaluate('(z-x) * (t-y)'))

输出:

1.02 s ± 17.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
317 ms ± 8.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 2011-10-18
    • 2017-03-27
    • 2018-10-22
    • 1970-01-01
    • 2017-10-20
    相关资源
    最近更新 更多