在Python中对非均匀网格进行移位数组

3

我想知道在Numpy或SciPy中是否有Python功能可以将数组移动到非均匀网格上。 我已经创建了一个最小示例来说明这个过程,但在这个最小示例中似乎并不起作用:

import numpy as np
import matplotlib.pyplot as pyt

def roll_arrays( a, shift_values,x_grid ):
    #from scipy.interpolate import interp1d
    
    x_max         = np.amax(x_grid)    
    total_items   = a.shape[0]  
    the_ddtype    = a.dtype 
       
    result = np.zeros( (a.shape[0], a.shape[1] ), dtype=the_ddtype )    
   
    
    for k in range( total_items ):        
        edge_val_left  = a[k,0]
        edge_val_right = a[k,-1]     
       
        #extend grid to edges with boundary values (flat extrapolation)
        extended_boundary = np.abs( shift_values[k] )#positive or negative depending on shift 
        
        if( shift_values[k] != 0.0 ):
                   
            x0_right          = np.linspace( x_max +1e-3, x_max + 1e-3 + extended_boundary, 10 )
            x0_left           = np.linspace( -x_max - 1e-3 -extended_boundary, -x_max - 1e-3, 10 )
            if( shift_values[k]>0.0 ):
                #we fill left values
                x_dense_grid  = np.concatenate( ( x0_left, x_grid + shift_values[k] ) ) 
                ynew          = np.concatenate(  ( edge_val_left*np.ones( 10 ), a[k,:] )  )            
                
            elif( shift_values[k]<0.0 ):
                x_dense_grid  = np.concatenate( ( x_grid + shift_values[k], x0_right ) )               
                ynew          = np.concatenate(  ( a[k,:], edge_val_right*np.ones( 10 ) )  ) 
            
                                             
            ###
            #return on the original grid                       
            f_interp    = np.interp( x_grid, x_dense_grid, ynew )                
            result[k,:] = f_interp  
        
        else:
            #no shift
            result[k,:] = a[k,:]
             
    
    return result


x_geom     = np.array( [ 100*( 1.5**(-0.5*k) ) for k in range(1000)] )
x_geom_neg =-( x_geom )
x_geom = np.concatenate( (np.array([0.0]), np.flip(x_geom)) )
x_geom = np.concatenate( (x_geom_neg, x_geom) )

shifts = np.array([-1.0,-2.0,1.0])
f      = np.array( [ k**2/( x_geom**2 + k**4 ) for k in range(1,shifts.shape[0]+1)  ] )
fs     = roll_arrays( f, shifts, x_geom)

pyt.plot( x_geom, f[0,:], marker='.' )
pyt.plot( x_geom, fs[0,:], marker='.' )


print("done")

注意,在这种情况下,“x_grid”的数据点是以对数间隔分布的。有没有一种方法可以利用Scipy / Numpy进行这样的操作?通过插值方法或类似方法实现。
编辑:我注意到删除有关边界移位(执行平坦外推)的if,elif,else语句似乎解决了问题;但我仍然认为这对于应该已经存在于Python中的问题来说过于天真; 所以问题仍然存在。

我删除了我的回答,因为我似乎完全误解了你想要的内容;我认为我无法再帮助你,因为我看不到或理解你想要或需要什么。 - Tempman383838
我很感激您的关注。问题简化为一个数组的简单移位,但当“x”不是均匀间隔的点集时,即对于不同的“i”索引,距离x[i+1]-x[i]是不同的。对于网格的每个值x[i],都有一个相应的数组f[i]。对于示例中的函数,我们想要将定义在“x”上的f[x](假设为0分量f[0,:])向左移动“shift=-1.0”的量。问题是如何恢复原始网格“x”中移位后的函数f[x + shift]的数据点。 - Zarathustra
1个回答

1
如果我理解问题正确的话,np.interp 将会满足你的需求(默认情况下它会复制边缘的值):
def roll_arrays(a, shift_values, x_grid):
    total_items = a.shape[0]
    result = np.zeros_like(a)

    for k in range(total_items):
        if shift_values[k] != 0.0:
            # shift the x values
            x_grid_shifted = x_grid + shift_values[k]
            # interpolate back to the original grid
            f_interp = np.interp(x_grid, x_grid_shifted, a[k, :])
            result[k, :] = f_interp
        else:
            # no shift
            result[k, :] = a[k, :]

    return result

对于问题中的示例输入,这将会给出非常接近的结果。
fs_expected = np.array([k ** 2 / ((x_geom - shift) ** 2 + k ** 4) for k, shift in enumerate(shifts, start=1)])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接