我正在编写一个函数,该函数接受长度为200的numpy数组a
和大小为200 x 200的矩阵M
,并执行以下操作:
for i in range(len(a)):
x = a[i]
for j in range(len(a)):
y = a[j]
z = M[i][j]
d[i][j] = 2 * z/(y+x)
return d
如何对这段代码进行矢量化处理以提高运行时间?
问题来源:stackoverflow
Numpy的ufunc都具有external
方法,以在两个数组上“交叉”执行操作。因此,为了避免大多数中间计算并尽可能向量化:
def f(M, a):
return 2 * M / np.add.outer(a, a)
对于这样的事情,我发现最好总是分步进行,并尝试找到正确的einsum
表达式。
# the definition given in the original question,
# before the z / (y + x) update
def f0():
d = np.empty((3,3))
for i in range(len(a)):
x = a[i]
for j in range(len(a)):
y = a[j]
z = M[i][j]
d[i][j] = 2 * x/(y+z)
return d
# rewrite things inlined
def f1():
d = np.empty((3,3))
for i in range(len(a)):
for j in range(len(a)):
d[i, j] = 2 * a[i]/(a[j] + M[i, j])
return d
# factor out broadcasting
def f2():
d = np.empty((3,3))
for i in range(len(a)):
m = a + M[i, :]
for j in range(len(a)):
d[i,j] = 2 * a[i]/m[j]
return d
# more broadcasting
def f3():
d = np.empty((3,3))
m = a + M
for i in range(len(a)):
for j in range(len(a)):
d[i,j] = 2 * a[i]/m[i,j]
return d
# now turn loops into einsums
def f4():
d = np.empty((3,3))
m = 1/(a + M)
d[:,:] = 2 * np.einsum('i,ij->ij', a, m)
return d
# collect everything
def f5():
return np.einsum('i,ij->ij', a, 2 / (a + M))
回答来源:stackoverflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。