基于大量 xy 点从二维数组中提取插值

Extract interpolated values from a 2D array based on a large set of xy points

我有一个相当大的 1000 x 4000 像素 xr.DataArray return 来自 OpenDataCube 查询,以及一大组(> 200,000)的 xy 点值. 我需要将数组采样到 return 每个 xy 点下的值,以及 return 内插值 (例如,如果该点落在0 和一个 1.0 像素,值 returned 应该是 0.5).

xr.interp 让我可以轻松地对插值进行采样,但它 return 是所有 xy 值的每个组合的巨大矩阵,而不仅仅是每个 xy 点本身的值。我试过使用 np.diagonal 只提取 xy 点值,但这很慢,很快就会遇到内存问题并且感觉效率低下,因为我仍然需要等待每个值的组合被插值通过 xr.interp.

可重现的例子

(仅使用 10,000 个样本点(理想情况下,我需要可以扩展到 > 200,000 或更多的样本点):

# Create sample array
width, height = 1000, 4000
val_array = xr.DataArray(data=np.random.randint(0, 10, size=(height, width)).astype(np.float32),
                         coords={'x': np.linspace(3000, 5000, width),
                                 'y': np.linspace(-3000, -5000, height)}, dims=['y', 'x'])

# Create sample points
n = 10000
x_points = np.random.randint(3000, 5000, size=n)
y_points = np.random.randint(-5000, -3000, size=n)

当前方法

%%timeit

# ATTEMPT 1
np.diagonal(val_array.interp(x=x_points, y=y_points).squeeze().values)
32.6 s ± 1.01 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

有谁知道实现此目的的更快或更有效内存的方法吗?

为了避免满格,需要引入新的维度。

x = xr.DataArray(x_points, dims='z')
y = xr.DataArray(y_points, dims='z')
val_array.interp(x=x, y=y)

将沿着新的 z 维度给你一个数组:

<xarray.DataArray (z: 10000)>
array([4.368132, 2.139781, 5.693636, ..., 3.7505  , 3.713589, 2.28494 ])
Coordinates:
    x        (z) int64 4647 4471 4692 3942 3468 ... 3040 3993 3027 4427 3749
    y        (z) int64 -3744 -4074 -3634 -3289 -3221 ... -4195 -4131 -4814 -3362
Dimensions without coordinates: z

36.9 ms ± 1.25 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Advanced Interpolation 上的 xarray 文档中有一个很好的示例。