Python 如何在2D numpy数组中设置向量[u,v]的阈值?

Python 如何在2D numpy数组中设置向量[u,v]的阈值?,python,arrays,numpy,threshold,Python,Arrays,Numpy,Threshold,我编写了一个阈值函数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] 我可以使用哪些其他方法/功能更有效地解决此问题(使用列表理解或其他方法) 下面是一些代码: 将numpy导入为np 导入时间 开始=时间。时间()

我编写了一个阈值函数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]

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

下面是一些代码:

将numpy导入为np
导入时间
开始=时间。时间()
def TH(arr,阈值):
对于idx,枚举中的值(arr):
对于i,枚举中的项(值):
如果np.abs(项目[0])<阈值和np.abs(项目[1])<阈值:
arr[idx][i][0]=0.0
arr[idx][i][1]=0.0
返回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,阈值=1)
印刷品(a)
end=time.time()
打印(“运行时:”,结束-开始)
输出:

[[0.0]
[3.  4. ]
[3.  0.1]]
[[0.  2. ]
[0.  0. ]
[0.3 3. ]]
[[0.  0. ]
[0.  0. ]
[0.5 5. ]]]
运行时间:0.0009984970092773438

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

mask = (np.abs(arr[...,0]) < threshold) & (np.abs(arr[...,1]) < threshold)
arr[mask] = 0
或者,在计算绝对值后使用相同的切片方法-

mask = (ab[...,0] < threshold) & (ab[...,1] < threshold)
时间安排-

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
[209]中的
:arr=np.random.rand(10801920,2)
在[210]中:阈值=1

在[211]:%timeit(np.abs(arr[…,0])中,到目前为止,我更新了两个阈值函数。以下是不同方法的执行时间(在25帧视频上运行):我的方法,322.09秒。你提出的第一种方法,28.78秒。第二种方法,29.32秒。第三种方法,28.36秒。平均而言,你提出的所有解决方案似乎比我最初的功能快10倍。感谢你的帮助和清楚的解释!@MarkH感谢你带着这些性能数据回来!好奇-t是什么您正在使用的
arr
的典型形状?我使用的每个阵列都保存表示视频帧某些特征的数据(RGB值、光流向量[u,v]、大小、角度…。因此,我的阵列具有与帧大小相似的形状(例如:(10801920,2))。在阈值和清理之后,我将好的值存储在一个数组中,以训练机器学习模型。此数组的形状为(51840000,5)对于25帧。上下文:我正在研究人类动作识别。@MarkH又添加了一个使用多核的
numexpr
。这可以进一步提高性能。我对它进行了测试,没有发现在计时方面有任何差异。每个循环的计时改进是否会如此之小,以至于总体变化可以忽略不计?(10.2-4.79)ms*25循环=在25帧上运行时快135.25ms。注意:由于我使用的数学模型,我的代码中存在大约+-0.5s的差异,这可能就是我看不到差异的原因。
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