本文介绍了用于 2D 外推样条函数的 Python Scipy?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为二维矩阵编写一个外推样条函数.我现在拥有的是一维数组的外推样条函数,如下所示.scipy.interpolate.InterpolatedUnivariateSpline() 被使用.

I'd like to write an extrapolated spline function for a 2D matrix. What I have now is an extrapolated spline function for 1D arrays as below. scipy.interpolate.InterpolatedUnivariateSpline() is used.

import numpy as np 
import scipy as sp 

def extrapolated_spline_1D(x0,y0):
    x0 = np.array(x0)
    y0 = np.array(y0)
    assert x0.shape == y.shape 

    spline = sp.interpolate.InterpolatedUnivariateSpline(x0,y0)
    def f(x, spline=spline):
        return np.select(
            [(x<x0[0]),              (x>x0[-1]),              np.ones_like(x,dtype='bool')], 
            [np.zeros_like(x)+y0[0], np.zeros_like(x)+y0[-1], spline(x)])

    return f

它需要 x0,即函数的定义位置,以及 y0,即相应的值.当 x x0[-1] 时,y = y0[-1].这里,假设 x0 为升序.

It takes x0, which is where the function is defined, and y0, which is the according values. When x < x0[0], y = y0[0]; and when x > x0[-1], y = y0[-1]. Here, assuming x0 is in an ascending order.

我想要一个类似的外推样条函数来处理使用 np.select()extrapolated_spline_1D.我认为 scipy.interpolate.RectBivariateSpline() 可能会有所帮助,但我不知道该怎么做.

I want to have a similar extrapolated spline function for dealing with 2D matrices using np.select() as in extrapolated_spline_1D. I thought scipy.interpolate.RectBivariateSpline() might help, but I'm not sure how to do it.

作为参考,我当前的 extrapolated_spline_2D 版本非常慢.基本思想是:

For reference, my current version of the extrapolated_spline_2D is very slow. The basic idea is:

(1) 首先,给定一维数组x0、y0和二维数组z2d0作为输入,制作nx0个extrapolated_spline_1D函数,y0_spls,每个都代表在y0上定义的一层z2d0;

(1) first, given 1D arrays x0, y0 and 2D array z2d0 as input, making nx0 extrapolated_spline_1D functions, y0_spls, each of which stands for a layer z2d0 defined on y0;

(2)秒,对于一个不在网格上的点(x,y),计算nx0个值,每个都等于y0_spls[i](y);

(2) second, for a point (x,y) not on the grid, calculating nx0 values, each equals to y0_spls[i](y);

(3) 第三,用extrapolated_spline_1D将 (x0, y0_spline_1D) 拟合到 x_spl 并返回 x_spl(x) 作为最终结果.

(3) third, fitting (x0, y0_spls[i](y)) with extrapolated_spline_1D to x_spl and returning x_spl(x) as the final result.

def extrapolated_spline_2D(x0,y0,z2d0): 
    '''    
    x0,y0 : array_like, 1-D arrays of coordinates in strictly monotonic order. 
    z2d0  : array_like, 2-D array of data with shape (x.size,y.size).
    '''    
    nx0 = x0.shape[0]
    ny0 = y0.shape[0]
    assert z2d0.shape == (nx0,ny0)

    # make nx0 splines, each of which stands for a layer of z2d0 on y0 
    y0_spls = [extrapolated_spline_1D(y0,z2d0[i,:]) for i in range(nx0)]

    def f(x, y):     
        '''
        f takes 2 arguments at the same time --> x, y have the same dimention
        Return: a numpy ndarray object with the same shape of x and y
        '''
        x = np.array(x,dtype='f4')
        y = np.array(y,dtype='f4') 
        assert x.shape == y.shape        
        ndim = x.ndim 

        if ndim == 0:    
            '''
            Given a point on the xy-plane. 
            Make ny = 1 splines, each of which stands for a layer of new_xs on x0
            ''' 
            new_xs = np.array([y0_spls[i](y) for i in range(nx0)]) 
            x_spl  = extrapolated_spline_1D(x0,new_xs)
            result = x_spl(x)

        elif ndim == 1:
            '''
            Given a 1-D array of points on the xy-plane. 
            '''
            ny     = len(y)            
            new_xs = np.array([y0_spls[i](y)                 for i in range(nx0)]) # new_xs.shape = (nx0,ny)       
            x_spls = [extrapolated_spline_1D(x0,new_xs[:,i]) for i in range(ny)]
            result = np.array([x_spls[i](x[i])               for i in range(ny)])

        else:
            '''
            Given a multiple dimensional array of points on the xy-plane.  
            '''
            x_flatten = x.flatten()
            y_flatten = y.flatten()     
            ny = len(y_flatten)       
            new_xs = np.array([y0_spls[i](y_flatten)         for i in range(nx0)])         
            x_spls = [extrapolated_spline_1D(x0,new_xs[:,i]) for i in range(ny)]
            result = np.array([x_spls[i](x_flatten[i])       for i in range(ny)]).reshape(y.shape)
        return result      
    return f

推荐答案

我做过一个类似的工作叫做 GlobalSpline2D 此处,它在线性、三次或五次样条曲线下都可以完美运行.

I've done a similar work called GlobalSpline2D here, and it works perfectly under either liner, cubic, or quintic splines.

基本上它继承了interp2d,并通过 InterpolatedUnivariateSpline.它们都是 scipy 内部函数.

Basically it inherits interp2d, and promoting the usage to 2D extrapolation by InterpolatedUnivariateSpline. Both of them are scipy internal functions.

其用法应参考文档 以及interp2d 的调用方法.

这篇关于用于 2D 外推样条函数的 Python Scipy?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 16:50