如何在二维numpy数组中对向量[u,v]设置阈值?

我编写了一个阈值函数TH(arr,threshold),该函数接受矢量[u,v]的2D数组,如果u和v的绝对值均低于指定的阈值,则将它们设置为0.

该函数由2个for循环组成并完成工作,但是计算量很大(我正在大型数据集上运行它).

例子:

[u,v]->输出(阈值= 1)

[2,2]-> [2,2]

[2,.1]-> [2,.1]

[.1,.1]-> [0,0]

我还可以使用其他哪些方法/功能来更有效地解决此问题(使用列表理解或其他方法)?

这是一些代码:

import numpy as np
import time
start = time.time()

def TH(arr, threshold):
    for idx, value in enumerate(arr):
        for i, item in enumerate(value):
            if np.abs(item[0]) < threshold and np.abs(item[1]) < threshold:
                arr[idx][i][0] = 0.0
                arr[idx][i][1] = 0.0
    return arr

a = np.array([[[.5,.8], [3,4], [3,.1]],
              [[0,2], [.5,.5], [.3,3]],
              [[.4,.4], [.1,.1], [.5,5]]])

a = TH(a, threshold = 1)
print(a)

end = time.time()
print("Run time: ", end-start)

输出:

[[[0.  0. ]
  [3.  4. ]
  [3.  0.1]]

 [[0.  2. ]
  [0.  0. ]
  [0.3 3. ]]

 [[0.  0. ]
  [0.  0. ]
  [0.5 5. ]]]

Run time:  0.0009984970092773438

解决方法:

只需沿最后一个轴对这两个元素进行切片,并以矢量化的方式执行相同的操作即可得到一个掩码,最后用掩码将其索引到输入数组中以分配0-

mask = (np.abs(arr[...,0]) < threshold) & (np.abs(arr[...,1]) < threshold)
arr[mask] = 0

请注意,arr […,0]是放置arr [:,:,0]的另一种方法,旨在沿最后一个轴切片通用ndarray.同样,对于arr […,1].

另外,也可以预先计算绝对值,并使用它们与阈值进行比较,并针对最后一个轴查找所有匹配项以获取相同的掩码-

ab = np.abs(arr)
mask = (ab < threshold).all(-1)

或者,在计算绝对值后使用相同的切片方法-

mask = (ab[...,0] < threshold) & (ab[...,1] < threshold)

对于大型阵列,我们还可以利用numexpr module

import numexpr as ne

m0 = ne.evaluate('abs(arr)<threshold')
mask = m0[...,0] & m0[...,1]

时间-

In [209]: arr = np.random.rand(1080,1920,2)

In [210]: threshold = 1

In [211]: %timeit (np.abs(arr[...,0])<threshold) & (np.abs(arr[...,1])<threshold)
100 loops, best of 3: 10.2 ms per loop

In [212]: %timeit np.abs(arr).all(1)
10 loops, best of 3: 34.5 ms per loop

In [213]: %%timeit
     ...: ab = np.abs(arr)
     ...: (ab[...,0] < threshold) & (ab[...,1] < threshold)
     ...: 
100 loops, best of 3: 11 ms per loop

In [214]: %%timeit
     ...: m0 = ne.evaluate('abs(arr)<threshold')
     ...: m0[...,0] & m0[...,1]
     ...: 
100 loops, best of 3: 4.79 ms per loop
上一篇:scroll-view组件


下一篇:剑指Offer(牛客版)--面试题13:机器人的运动范围