2013-03-18 3 views
7

내가 정기적으로 보간하려고 마스크는 Scipy의 RectBivariateSpline 클래스를 사용 windstress 데이터를 격자. 일부 격자 점에서 입력 데이터에 NaN 값으로 설정된 잘못된 데이터 항목이 포함되어 있습니다. 우선, bidimensional interpolation에서 Scott's question에 대한 해답을 사용했습니다. 내 데이터를 사용하여 보간법은 NaN 만 포함하는 배열을 반환합니다. 또한 데이터가 비정형이고 SmoothBivariateSpline 클래스를 사용한다고 가정하고 다른 접근법을 시도했습니다. 분명히 데이터 배열의 모양이 (719 x 2880)이므로 구조화되지 않은 보간을 사용하기에는 너무 많은 데이터 요소가 있습니다.이중 변수 구조의 NaN 값을 큰 배열의 보간

from __future__ import division 
import numpy 
import pylab 

from scipy import interpolate 


# The signal and lots of noise 
M, N = 20, 30 # The shape of the data array 
y, x = numpy.mgrid[0:M+1, 0:N+1] 
signal = -10 * numpy.cos(x/50 + y/10)/(y + 1) 
noise = numpy.random.normal(size=(M+1, N+1)) 
z = signal + noise 


# Some holes in my dataset 
z[1:2, 0:2] = numpy.nan 
z[1:2, 9:11] = numpy.nan 
z[0:1, :12] = numpy.nan 
z[10:12, 17:19] = numpy.nan 


# Interpolation! 
Y, X = numpy.mgrid[0.125:M:0.5, 0.125:N:0.5] 
sp = interpolate.RectBivariateSpline(y[:, 0], x[0, :], z) 
Z = sp(Y[:, 0], X[0, :]) 

sel = ~numpy.isnan(z) 
esp = interpolate.SmoothBivariateSpline(y[sel], x[sel], z[sel], 0*z[sel]+5) 
eZ = esp(Y[:, 0], X[0, :]) 


# Comparing the results 
pylab.close('all') 
pylab.ion() 

bbox = dict(edgecolor='w', facecolor='w', alpha=0.9) 
crange = numpy.arange(-15., 16., 1.) 

fig = pylab.figure() 
ax = fig.add_subplot(1, 3, 1) 
ax.contourf(x, y, z, crange) 
ax.set_title('Original') 
ax.text(0.05, 0.98, 'a)', ha='left', va='top', transform=ax.transAxes, 
    bbox=bbox) 

bx = fig.add_subplot(1, 3, 2, sharex=ax, sharey=ax) 
bx.contourf(X, Y, Z, crange) 
bx.set_title('Spline') 
bx.text(0.05, 0.98, 'b)', ha='left', va='top', transform=bx.transAxes, 
    bbox=bbox) 

cx = fig.add_subplot(1, 3, 3, sharex=ax, sharey=ax) 
cx.contourf(X, Y, eZ, crange) 
cx.set_title('Expected') 
cx.text(0.05, 0.98, 'c)', ha='left', va='top', transform=cx.transAxes, 
    bbox=bbox) 

다음과 같은 결과 제공 : Bivariate gridding. (a) The original constructed data, (b) Scipy's RectBivariateSpline and (c) SmoothBivariateSpline classes.

그림은 (a)와 Scipy의 RectBivariateSpline를 사용하여 결과 (B 구축 된 데이터 맵을 보여줍니다

내 문제를 설명하기 위해 나는 다음과 같은 스크립트를 생성) 및 SmoothBivariateSpline (c) 클래스를 사용합니다. 최초의 보간에서는, NaN만을 가지는 배열이 생성됩니다. 이상적으로 나는 계산 집약적 인 두 번째 보간법과 비슷한 결과를 기대했을 것입니다. 도메인 영역 외부의 데이터 외삽이 반드시 필요한 것은 아닙니다.

+1

누락 된 데이터로 구조 보간을 수행 할 수 없습니다. 구조화되지 않은 보간도 옵션이 아닌 경우 도메인을 직사각형 덩어리로 분해 한 다음 누락 된 데이터가있는 모든 곳에서 구조화되지 않은 보간을 수행하고 다른 곳에서는 구조화 할 수 있습니다. 선형 보간법을 사용하는 경우 도메인을 분할하는 것이 유일한 문제입니다. 그러나 3 차 스플라인을 사용하는 경우 청크 사이의 경계 조건을 처리해야합니다. 그 방법에 대해서는 잘 모릅니다. – Jaime

+0

또한 'scipy.interpolate.griddata'에게 smoothbivariatespline과 비슷한 촬영을 줄 수 있습니다. –

답변

0

griddata을 사용할 수 있습니다. 유일한 문제는 가장자리를 잘 처리하지 못하는 것입니다. 의 라인을 따라, 당신은 메모리가 부족하면

from __future__ import division 
import numpy 
import pylab 
from scipy import interpolate 


# The signal and lots of noise 
M, N = 20, 30 # The shape of the data array 
y, x = numpy.mgrid[0:M+1, 0:N+1] 
signal = -10 * numpy.cos(x/50 + y/10)/(y + 1) 
noise = numpy.random.normal(size=(M+1, N+1)) 
z = signal + noise 


# Some holes in my dataset 
z[1:2, 0:2] = numpy.nan 
z[1:2, 9:11] = numpy.nan 
z[0:1, :12] = numpy.nan 
z[10:12, 17:19] = numpy.nan 

zi = numpy.vstack((z[::-1,:],z)) 
zi = numpy.hstack((zi[:,::-1], zi)) 
y, x = numpy.mgrid[0:2*(M+1), 0:2*(N+1)] 
y *= 5 # anisotropic interpolation if needed. 

zi = interpolate.griddata((y[~numpy.isnan(zi)], x[~numpy.isnan(zi)]), 
       zi[~numpy.isnan(zi)], (y, x), method='cubic') 
zi = zi[:(M+1),:(N+1)][::-1,::-1] 

pylab.subplot(1,2,1) 
pylab.imshow(z, origin='lower') 
pylab.subplot(1,2,2) 
pylab.imshow(zi, origin='lower') 
pylab.show() 

, 당신은 당신의 데이터를 분할 수 :이 다음은 예입니다 ... 당신의 데이터가 방식에 따라 반영 예를 들어으로 도움이 될 수

def large_griddata(data_x, vals, grid, method='nearest'): 
    x, y = data_x 
    X, Y = grid 
    try: 
     return interpolate.griddata((x,y),vals,(X,Y),method=method) 
    except MemoryError: 
     pass 

    N = (np.min(X)+np.max(X))/2. 
    M = (np.min(Y)+np.max(Y))/2. 

    masks = [(x<N) & (y<M), 
      (x<N) & (y>=M), 
      (x>=N) & (y<M), 
      (x>=N) & (y>=M)] 

    grid_mask = [(X<N) & (Y<M), 
      (X<N) & (Y>=M), 
      (X>=N) & (Y<M), 
      (X>=N) & (Y>=M)] 

    Z = np.zeros_like(X) 
    for i in range(4): 
     Z[grid_mask[i]] = large_griddata((x[masks[i]], y[masks[i]]), 
        vals[masks[i]], (X[grid_mask[i]], Y[grid_mask[i]]), method=method) 

    return Z