我正在使用scipy.interpolate.Rbf,它返回函数,以将大量RBF拟合到不同的点集,并将其输出存储在函数的向量中,如下所示
import scipy.interpolate as interp
for i in range(0,n):
# Gets data points for this particular iteration
data = get_data(i)
# Fits RBF to data points
zfun_smooth_rbf = interp.Rbf(data[:, 0], data[:, 1], data[:, 2], function='linear', smooth=0)
# Appends RBF function
rbf_fit.append(zfun_smooth_rbf)
然后我感兴趣的是运行所有函数来回归每个计算的RBF的值。目前我使用的是foor循环策略,类似于this问题中的答案,但这远非理想,因为它基本上按顺序运行
c = [float(f(x,y) for f in self.rbf_fit]
无论如何都可以通过一次通话来运行此通话吗?换句话说,我需要同时调用存储在数组中的所有函数。像c = self.rbf_fit[:](x,y)
这样的东西?
答案 0 :(得分:1)
我将尝试将__call__
的2 rbfi
合并为一个电话。
In [80]: from scipy.interpolate import Rbf
按照文档中的说明制作样本:
In [81]: x, y, z, d = np.random.rand(4, 50)
In [82]: rbfi0 = Rbf(x, y, z, d)
In [83]: xi = yi = zi = np.linspace(0, 1, 20)
In [84]: di0 = rbfi0(xi, yi, zi)
In [85]: di0
Out[85]:
array([ 0.26614249, 0.07429816, -0.01512205, 0.05134466, 0.24213774,
0.41653342, 0.45280185, 0.34763177, 0.17681661, 0.07186139,
0.16299749, 0.40416788, 0.641642 , 0.78828711, 0.79709639,
0.6530432 , 0.42473033, 0.24155719, 0.17008326, 0.179932 ])
制作第二个样本:
In [86]: x, y, z, d = np.random.rand(4, 50)
In [87]: rbfi1 = Rbf(x, y, z, d)
In [88]: di1 = rbfi1(xi, yi, zi)
In [89]: di1
Out[89]:
array([ 0.38975158, 0.39887118, 0.42430634, 0.48554998, 0.59403568,
0.71745345, 0.77483525, 0.70657269, 0.53545478, 0.34931526,
0.28960157, 0.45825098, 0.7538652 , 0.99950089, 1.14749381,
1.19019632, 1.12736371, 1.00558691, 0.87811695, 0.77231634])
查看rbfi
:
In [90]: rbfi0.nodes
Out[90]:
array([ -13.02451018, -3.05675802, 8.54073071, -81.47163716,
-5.74247623, 118.70153224, -1.39117053, -3.37170396,
....
-10.08326243, 8.9995743 , 3.83357612, -4.59815344,
-25.09981508, -2.8753806 , -0.63932038, 76.59402274,
0.26222997, -30.35280108])
In [91]: rbfi0.nodes.shape
Out[91]: (50,)
In [92]: rbfi1.nodes.shape
Out[92]: (50,)
In [93]: rbfi0.xi.shape
Out[93]: (3, 50)
In [94]: rbfi1.xi.shape
Out[94]: (3, 50)
在__call__
:
In [95]: xa = np.asarray([a.flatten() for a in [xi,yi,zi]], dtype=np.float_)
In [96]: xa.shape
Out[96]: (3, 20)
In [97]: r0 = rbfi0._call_norm(xa, rbfi0.xi)
In [98]: r1 = rbfi1._call_norm(xa, rbfi1.xi)
In [99]: r0.shape
Out[99]: (20, 50)
In [100]: r1.shape
Out[100]: (20, 50)
通过连接norm
数组,通过一次调用计算两个rbfi
的{{1}}:
xi
现在为In [102]: r01 = rbfi0._call_norm(xa, np.concatenate((rbfi0.xi, rbfi1.xi),axis=1))
In [103]: r01.shape
Out[103]: (20, 100)
In [104]: np.allclose(r0, r01[:,:50])
Out[104]: True
In [105]: np.allclose(r1, r01[:,50:])
dot`做同样的事情:
nodes' and
糟糕。我们想要两套20个;这一次适合所有100个节点。我需要做一些重塑。
In [110]: res01 = np.dot(rbfi0._function(r01), np.concatenate((rbfi0.nodes, rbfi1.nodes)))
In [111]: res01.shape
Out[111]: (20,)
2 In [133]: r01.shape
Out[133]: (20, 100)
In [134]: r01 = r01.reshape(20,2,50)
In [135]: nodes01 = np.concatenate((rbfi0.nodes, rbfi1.nodes))
In [136]: nodes01.shape
Out[136]: (100,)
In [137]: nodes01 = nodes01.reshape(2,50) # should have just stacked them
的{{1}}可卡座不同,所以我单独使用它们:
_function
使用更多样本,此列表将使用列表推导构建。
rbfi
现在,我可以为合并的In [138]: fr01 = [rbfi0._function(r01[:,0,:]), rbfi1._function(r01[:,1,:])]
In [139]: fr01[0].shape
Out[139]: (20, 50)
:
In [140]: fr01 = np.stack(fr01, axis=1)
In [141]: fr01.shape
Out[141]: (20, 2, 50)
np.dot
所以我设法用rbfi
替换了In [142]: res01 = np.einsum('ijk,jk->ij', fr01, nodes01)
In [143]: res01.shape
Out[143]: (20, 2)
In [144]: np.allclose(res0, res01[:,0])
Out[144]: True
In [145]: np.allclose(res1, res01[:,1])
Out[145]: True
In [149]: di01 = np.stack([rbfi0(xi, yi, zi), rbfi1(xi, yi, zi)],axis=1)
In [150]: di01.shape
Out[150]: (20, 2)
In [151]: np.allclose(di01, res01)
次迭代。我不知道这是否节省了时间。这可能取决于In [149]
电话与其余In [138]
的比较费用。
在我的例子中
_function
我不知道您的参数rbfi.__call__
是否有所作为。如果相应的In [131]: rbfi0._function
Out[131]: <bound method Rbf._h_multiquadric of <scipy.interpolate.rbf.Rbf object at 0xab002fac>>
属性相同,那么我可以用
function='linear', smooth=0
这可以让您了解如何加快_function
的迭代速度,甚至可以用“&#39;向量”替换它。操作
对于默认函数,看起来差异仅在于rbfi0._function(r01).reshape(20,2,50)
值:
rbfi