21

我需要将 2D 数据重新采样为常规网格。

这就是我的代码的样子:

import matplotlib.mlab as ml
import numpy as np

y = np.zeros((512,115))
x = np.zeros((512,115))

# Just random data for this test:
data = np.random.randn(512,115)

# filling the grid coordinates:    
for i in range(512):
    y[i,:]=np.arange(380,380+4*115,4)

for i in range(115):
    x[:,i] = np.linspace(-8,8,512)
    y[:,i] -=  np.linspace(-0.1,0.2,512)

# Defining the regular grid
y_i = np.arange(380,380+4*115,4)
x_i = np.linspace(-8,8,512)

resampled_data = ml.griddata(x,y,data,x_i,y_i)

(512,115) 是二维数据的形状,我已经安装了 mpl_toolkits.natgrid。

我的问题是我得到了一个掩码数组,其中大多数条目是 nan,而不是一个主要由常规条目组成的数组,而边界处只有 nan。

有人可以指出我做错了什么吗?

谢谢!

4

1 回答 1

75

将您的代码示例与问题的标题进行比较,我认为您有点困惑...

在您的示例代码中,您正在创建规则网格化的随机数据,然后将其重新采样到另一个规则网格上。您的示例中的任何地方都没有不规则数据...

(此外,代码不会按原样运行,您应该查看meshgrid而不是循环生成您的 x & y 网格。)

如果您想重新采样已经定期采样的网格,就像您在示例中所做的那样,有比 griddata 或我将在下面描述的任何方法更有效的方法。(scipy.ndimage.map_coordinates很适合您的问题,在这种情况下。)

但是,根据您的问题,听起来您有不规则间隔的数据,您想要插入到规则网格中。

在这种情况下,您可能会有以下几点:

import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt

# Bounds and number of the randomly generated data points
ndata = 20
xmin, xmax = -8, 8
ymin, ymax = 380, 2428

# Generate random data
x = np.random.randint(xmin, xmax, ndata)
y = np.random.randint(ymin, ymax, ndata)
z = np.random.random(ndata)

# Plot the random data points
plt.scatter(x,y,c=z)
plt.axis([xmin, xmax, ymin, ymax])
plt.colorbar()
plt.show()

随机生成的数据

然后,您可以像以前一样插入数据...(继续上面的代码片段...)

# Size of regular grid
ny, nx = 512, 115

# Generate a regular grid to interpolate the data.
xi = np.linspace(xmin, xmax, nx)
yi = np.linspace(ymin, ymax, ny)
xi, yi = np.meshgrid(xi, yi)

# Interpolate using delaunay triangularization 
zi = mlab.griddata(x,y,z,xi,yi)

# Plot the results
plt.figure()
plt.pcolormesh(xi,yi,zi)
plt.scatter(x,y,c=z)
plt.colorbar()
plt.axis([xmin, xmax, ymin, ymax])
plt.show()

插值不佳的数据

但是,您会注意到网格中有很多工件。这是因为您的 x 坐标范围从 -8 到 8,而 y 坐标范围从 ~300 到 ~2500。插值算法试图使事物各向同性,而您可能需要高度各向异性的插值(以便在绘制网格时看起来是各向同性的)。

要纠正这一点,您需要创建一个新的坐标系来进行插值。没有一种正确的方法可以做到这一点。我在下面使用的将起作用,但“最佳”方式在很大程度上取决于您的数据实际代表什么。

(换句话说,使用你对数据正在测量的系统的了解来决定如何做。插值总是如此!除非你知道结果应该是什么样子,并且足够熟悉插值算法使用该先验信息对您有利!!还有比griddata默认使用的Delaunay三角剖分更灵活的插值算法,但是对于一个简单的例子来说很好......)

无论如何,一种方法是重新调整 x 和 y 坐标,使它们的范围大致相同。在这种情况下。我们将它们从 0 重新缩放到 1...(请原谅意大利面条字符串代码...我只是想以此作为示例...)

# (Continued from examples above...)
# Normalize coordinate system
def normalize_x(data):
    data = data.astype(np.float)
    return (data - xmin) / (xmax - xmin)

def normalize_y(data):
    data = data.astype(np.float)
    return (data - ymin) / (ymax - ymin)

x_new, xi_new = normalize_x(x), normalize_x(xi)
y_new, yi_new = normalize_y(y), normalize_y(yi)

# Interpolate using delaunay triangularization 
zi = mlab.griddata(x_new, y_new, z, xi_new, yi_new)

# Plot the results
plt.figure()
plt.pcolormesh(xi,yi,zi)
plt.scatter(x,y,c=z)
plt.colorbar()
plt.axis([xmin, xmax, ymin, ymax])
plt.show()

在归一化坐标系中插值的数据

无论如何,希望对您有所帮助......对不起答案的长度!

于 2010-10-05T20:08:36.380 回答