NumPy-涉及范围迭代器的向量化循环
没有for循环,有没有办法使这项工作可行?
Is there any way to make this work without for loops?
import import numpy as np
import matplotlib.pyplot as plt
L = 1
N = 255
dh = 2*L/N
dh2 = dh*dh
phi_0 = 1
c = int(N/2)
r_0 = L/2
arr = np.empty((N, N))
for i in range(N):
for j in range(N):
arr[i, j] = phi_0 if (i - c)**2 + (j - c)**2 < r_0**2/dh2 else 0
plt.imshow(arr)
我尝试调用function(x [None ,:],y [:, None]),其中:
I've tried calling function(x[None,:], y[:, None]), where:
function(i, j):
return phi_0 if (i - c)**2 + (j - c)**2 < r_0**2/dh2 else 0
但是它需要列出.any或.all方法.我正在寻找专门的无功能方法(没有功能和向量化). 非常感谢!
but it requires list .any or .all methods. I'm looking for specifically functionless method (without fromfunction and vectorization). Big thanks!
使用开放式网格的矢量化解决方案
我们可以使用两个 open 范围/网格数组作为N
来模拟与迭代器相同的行为-
Vectorized solution using open grids
We could use two open range/grid arrays for N
simulating the same behavior as the iterators -
I = np.arange(N)
mask = (I[:,None] - c)**2 + (I - c)**2 < r_0**2/dh2
out = np.where(mask,phi_0,0)
对于两个循环的通用范围
对于一般情况,我们将遍历两个循环直到分别表示M
和N
,我们可以使用
For the generic case where we would iterate through two loops that extend till say M
and N
respectively, we could make use of np.ogrid
to create those open grids and then use on the same lines -
I,J = np.ogrid[:M,:N]
mask = (I - c)**2 + (J - c)**2 < r_0**2/dh2
有关通用循环次数
对于一般数量的循环,只需创建与循环数一样多的变量即可.因此,对于三个循环:
For a generic number of loops, simply create as many variables as the number of loops. Hence, for three loops :
for i in range(M):
for j in range(N):
for k in range(P):
,我们会:
I,J,K = np.ogrid[:M,:N,:P]
,然后分别使用I,J,K
而不是i,j,k
进行像我们这里这样的元素操作.
, then use I,J,K
instead of i,j,k
respectively for element-wise operations like we have here.
在这种情况下替代最后一步
最后一步也可以通过逐元素乘法来实现,方法是将else
部分设置为0s
-
Last step could also be implemented with elementwise multiplication by scaling to phi_0
with mask
as the else
part is setting to 0s
-
out = mask*phi_0