我有一个从OpenDataCube查询返回的相当大的1000 x 4000像素xr.DataArray和一个大的xy点值集(>200000)。我需要对数组进行采样以返回每个xy点下的值,并返回插值(例如,如果点落在01.0像素之间的一半,则返回的值应为0.5)。
xr.interp让我可以轻松地对插值进行采样,但它返回一个包含所有xy值的每个组合的巨大矩阵,而不仅仅是每个xy点本身的值。我试过使用np.diagonal只提取xy点的值,但这很慢,很快就会遇到内存问题,而且感觉效率很低,因为我仍然需要等待通过xr.interp插入每个值组合。
可复制示例
(仅使用10000个采样点(理想情况下,我需要可以扩展到大于200000或更多的采样点):

# 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)

在xarray文档中有一个很好的例子。

08-19 20:27