Python - 对于大量数据的2D数组插值

8

我希望对一个大小为4x4的二维数组"test"进行插值,这只是一个示例,实际上要接近1000x1000。插值网格的形状应该是8x8。

import numpy as np

X = np.arange(0,4,1)
Y = np.arange(0,4,1)

points = np.vstack((X,Y))
points = points.T #my coordinates

#my values as a 2D array
test = np.array([[ 1.2514318 ,  1.25145821,  1.25148472,  1.25151133],
       [ 1.25087456,  1.25090105,  1.25092764,  1.25095435],
       [ 1.25031581,  1.25034238,  1.25036907,  1.25039586],
       [ 1.24975557,  1.24978222,  1.24980898,  1.24983587]])

我尝试使用griddata,但似乎只适用于1D是吗?就像错误信息告诉我一样,我有“不同数量的值和点”。我犯了什么错误吗?

from scipy.interpolate import griddata
grid_x, grid_y = np.mgrid[0:4:8j, 0:4:8j]
grid_z0 = griddata(points, test, (grid_x, grid_y), method='linear')
2个回答

8
你可以使用 scipy.interpolate.interp2dnumpy.meshgrid 来完成此操作。
你需要确保新的X和Y范围与旧范围相同,只是步长更小。这很容易用 np.linspace 实现:
import numpy as np
from scipy import interpolate

mymin,mymax = 0,3
X = np.linspace(mymin,mymax,4)
Y = np.linspace(mymin,mymax,4)

x,y = np.meshgrid(X,Y)

test = np.array([[ 1.2514318 ,  1.25145821,  1.25148472,  1.25151133],
       [ 1.25087456,  1.25090105,  1.25092764,  1.25095435],
       [ 1.25031581,  1.25034238,  1.25036907,  1.25039586],
       [ 1.24975557,  1.24978222,  1.24980898,  1.24983587]])

f = interpolate.interp2d(x,y,test,kind='cubic')

# use linspace so your new range also goes from 0 to 3, with 8 intervals
Xnew = np.linspace(mymin,mymax,8)
Ynew = np.linspace(mymin,mymax,8)

test8x8 = f(Xnew,Ynew)

print test8x8
>>> [[ 1.2514318   1.25144311  1.25145443  1.25146577  1.25147714  1.25148852  1.25149991  1.25151133]
     [ 1.25119317  1.25120449  1.25121583  1.25122719  1.25123856  1.25124995  1.25126137  1.25127281]
     [ 1.25095426  1.2509656   1.25097695  1.25098832  1.25099971  1.25101112  1.25102255  1.25103401]
     [ 1.25071507  1.25072642  1.25073779  1.25074918  1.25076059  1.25077201  1.25078346  1.25079494]
     [ 1.25047561  1.25048697  1.25049835  1.25050976  1.25052119  1.25053263  1.2505441   1.25055558]
     [ 1.25023587  1.25024724  1.25025864  1.25027007  1.25028151  1.25029297  1.25030446  1.25031595]
     [ 1.24999585  1.25000724  1.25001866  1.2500301   1.25004156  1.25005304  1.25006453  1.25007605]
     [ 1.24975557  1.24976698  1.24977841  1.24978985  1.24980132  1.24981281  1.24982433  1.24983587]] 

1
可以!;) 但对于我的情况,似乎出现了“数据点过多无法插值”的错误 :( - user3601754
你的新数组有多大?也许你可以将它分成子数组来执行插值,然后再将它们拼接在一起? - tmdavison
1
你可以通过为 xy 坐标创建一个开放式网格来减少内存开销,即一个 (nx, 1) 数组和一个 (1, ny) 数组,而不是两个 (nx, ny) 数组。例如,x, y = np.meshgrid(X, Y, sparse=True)x, y = np.ix_(X, Y) - ali_m
1
scipy.interpolate.RegularGridInterpolator难道不应该更高效地完成这项工作吗? - fdermishin
你为什么在这里将3作为“mymax”?我不确定这个选择会如何影响最终结果。 - curious_cosmo

1

一个方便快捷的方法是使用skimage.transform.resize。它在大型网格上也对我很有效:

import numpy as np
from skimage.transform import resize

test = np.random.rand(1000,1000)

dim1, dim2 = 8, 8

test_resized = resize(test,(dim1,dim2))

print(test_resized.shape)
>>> (8, 8)

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