Python 如何在2D 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] 我可以使用哪些其他方法/功能更有效地解决此问题(使用列表理解或其他方法) 下面是一些代码: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 导入时间 开始=时间。时间()
将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