Python中的批次调用函数数组

2024-09-30 01:25:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用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问题中的答案,但这远不是理想的,因为它基本上是按顺序运行的

^{pr2}$

有没有办法只打一个电话打这个电话?换句话说,我需要同时调用数组中存储的所有函数。像c = self.rbf_fit[:](x,y)之类的?在


Tags: 函数fordatafunctionscipythispointsfit
1条回答
网友
1楼 · 发布于 2024-09-30 01:25:40

我将尝试将2rbfi__call__组合成一个调用。在

In [80]: from scipy.interpolate import Rbf

按照文档中的说明制作样本:

^{pr2}$

制作第二个样本:

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)

用一个调用计算两个rbfinorm,方法是连接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:])

现在对nodes' and点执行相同的操作:

In [110]: res01 = np.dot(rbfi0._function(r01), np.concatenate((rbfi0.nodes, rbfi1.nodes)))
In [111]: res01.shape
Out[111]: (20,)

哦。我们需要两组20个;这一次适合所有100个节点。我需要做些整形。在

^{8}$

2rbfi_function可调用项不同,因此我分别使用它们:

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)

现在我可以对组合的rbfi执行np.dot

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 [138]替换In [149]迭代。我不知道这是否能节省时间。这可能取决于_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属性相同,那么我可以用

rbfi0._function(r01).reshape(20,2,50)

这就提供了一个关于如何加快rbfi的迭代的想法,甚至可以用“vector”操作来替换它。在


看起来,对于默认函数,区别仅在于epsilon值:

In [156]: rbfi0._function??
Signature: rbfi0._function(r)
Source:   
    def _h_multiquadric(self, r):
        return np.sqrt((1.0/self.epsilon*r)**2 + 1)
File:      /usr/local/lib/python3.5/dist-packages/scipy/interpolate/rbf.py
Type:      method
In [157]: rbfi0.epsilon
Out[157]: 0.25663331561494024
In [158]: rbfi1.epsilon
Out[158]: 0.26163317529091562

相关问题 更多 >

    热门问题