批量调用Python中的函数数组

时间:2017-07-04 16:09:27

标签: python numpy scipy batch-processing

我正在使用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)这样的东西?

1 个答案:

答案 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