Python中有没有一种方法可以比双“ for”循环更快的方法来评估以内部向量为特征的函数?

时间:2019-08-24 14:57:42

标签: python arrays numpy-ndarray

我具有以下功能:

k=np.linspace(0,5,100) 
def f(x,y):
m=k
return sum(np.sin(m-x)*np.exp(-y**2))

我想获得在这两个数组上求值的f(x,y)的二维网格:

x=np.linspace(0,4,30)
y=np.linspace(0,2,70)

有没有比这种双“ for”循环更快的计算方法?

matrix=np.zeros((len(x),len(y)))
for i in range(len(x)):
    for j in range(len(y)):
        matrix[i,j]=f(x[i],y[j])
z=matrix.T

我试图通过这种方式使用“ numpy meshgrid”功能:

xx,yy=np.meshgrid(x, y)
z=f(xx,yy)

但是我收到以下错误消息:

ValueError:操作数不能与形状(100,)(70,30)一起广播。

2 个答案:

答案 0 :(得分:0)

这是一种麻木的方法。如果我们从您原始的阵列设置开始,

k = np.linspace(0,5,100)
x = np.linspace(0,4,30)
y = np.linspace(0,2,70)

然后

matrix = np.sin(k[:,np.newaxis] - x).sum(axis = 0)[:,np.newaxis]*np.exp(-y**2)

返回使用双“ for”循环计算出的相同(30,70)“矩阵”。

作为参考,https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html概述了numpy和https://www.numpy.org/devdocs/user/theory.broadcasting.html中的广播规则 很好地说明了如何使用这些规则。

答案 1 :(得分:0)

k=np.linspace(0,5,100) 
x=np.linspace(0,4,30)
y=np.linspace(0,2,70)

def f(x,y):
##    m=k
    return sum(np.sin(k-x)*np.exp(-y**2))

# original
def g():
    m = np.zeros((len(x),len(y)))
    for i in range(len(x)):
        for j in range(len(y)):
            m[i,j]=f(x[i],y[j])
    return m.T

# k.shape, x.shape, y.shape -> (100,), (30,), (70,)

# sine of each k minus each x
q = np.sin(k[:,None]-x)    # q.shape -> (100,30)

# [sine of each k minus each x] times [e to the negative (y squared)] 
r = np.exp(-y**2)    # r.shape --> (70,)
s = q[...,None] * r    # s.shape --> (100,30,70)

t = s.sum(0)
v = t.T    # v.shape -> (70,30)

assert np.all(np.isclose(v,g()))
assert np.all(v == g())

Broadcasting