Python np.meshgrid的循环计算是否可以矢量化?
我的代码中有一个部分,通过Python np.meshgrid的循环计算是否可以矢量化?,python,arrays,performance,for-loop,vectorization,Python,Arrays,Performance,For Loop,Vectorization,我的代码中有一个部分,通过for循环,我将np.meshgrid应用于my_数组切片的结果分配到占位符res_数组,如下所示: p = 360; q = 50; r = 50 my_array = np.random.rand(p, q, 2) res_array = np.zeros((p,q,r), dtype=np.float32) for i in range(p): x, x_ = np.meshgrid(my_array[i,:,0], my_array[i,:,0])
for
循环,我将np.meshgrid
应用于my_数组
切片的结果分配到占位符res_数组
,如下所示:
p = 360; q = 50; r = 50
my_array = np.random.rand(p, q, 2)
res_array = np.zeros((p,q,r), dtype=np.float32)
for i in range(p):
x, x_ = np.meshgrid(my_array[i,:,0], my_array[i,:,0])
res_array[i] = (x_-x)
在我的代码中还有一些类似的操作,我必须运行代码几千次。因此,速度成为一个问题。我在想,如果我可以不使用for
循环,我可以在这里节省一些时间,但是我自己无法做到
在没有for循环的情况下,如何实现这一点
编辑历史记录:
my_数组[i,:,1]
不用于上述snipet中。类似地,在另一个代码块中使用my_数组[I,:,1]
(此处未显示,但类似循环)。这就是我所说的“在我的代码中还有一些类似的操作…”my_array=np.random.rand(p,q,2)
res_array=np.array([x[1]-x[0]表示[np.meshgrid(my_array[i,:,0],my_array[i,:,0])表示范围(p)]中的i,np.float32)。重塑(p,q,r)
但是需要的时间比您多。您可以将np.meshgrid重写为更快的低级numpy操作:
p=360;q=50;r=50
my_array=np.random.rand(p,q,2)
res_数组=np.zeros((p,q,r),dtype=np.float32)
对于范围(p)内的i:
x=my_数组[None,i,:,0]。重复(q,轴=0)。重塑(q,q)
y=my_数组[None,i,:,0]。重复(q,轴=1)。重塑(q,q)
res_数组[i]=y-x
这个代码在我的机器上快了2倍。
Numba的@njit
可以用来加速上述代码(同样快3倍),但使用它可以实现更高效的实现。这是:
@njit(parallel=True)
def fasterImpl(我的_数组,p,q,r):
res_数组=np.zeros((p,q,r))
对于prange中的i(p):
对于范围(q)内的j:
对于范围(r)内的k:
res_数组[i,j,k]=my_数组[i,j,0]-my_数组[i,k,0]
返回res_数组
p=360;q=50;r=50
my_array=np.random.rand(p,q,2)
res_数组=fasterImpl(我的数组,p,q,r)
这个最终的实现比我机器上最初的实现快29倍 谢谢你。是的,我尝试了这个,但确实需要更长的时间。
我的_数组[I,:,1]
没有使用。这正常吗?你的意思是像np.meshgrid(我的数组[i,:,0],我的数组[i,:,1])
?谢谢你指出我们的@Jerome。类似地,我在另一个代码块中使用my_数组[I,:,1]
。这就是我所说的“在我的代码中还有一些类似的操作……”1/2@Jerome。谢谢你和我分享你的知识。与500次函数运行的基准测试相比,您的第一个实现已经为我提供了约5秒的速度优势。这对我很有帮助。2/2然而,当我尝试Numba
实现时,它给了我一个错误“类型数组的未知属性“repeat”。对不起,我以前没有用过Numba
。我知道你今天在这个问题上帮助了我。在那里,虽然我可以让代码运行,但没有任何明显的速度提升。我怀疑我是否正确使用了它。现在,我已经将基于Numba
的函数放在计算器函数之外,然后调用它。@your_boy_gorja我编辑了关于您的编辑的代码,以便可以轻松编辑代码。新的numba实现不再使用repeat
(问题可能与numba版本有关)。新的numba代码甚至更快。关于numba版本的计时,请注意第一次运行通常比较慢,因为numba必须编译它。您应该多次使用它,这样它才有用(您也可以在程序开始时调用该函数,以便在任何热路径之外对其进行编译)。此外,在您的机器上,parallel=True
+prange
可能速度较慢(请在没有测试的情况下进行测试)。