Извлечение интерполированных значений из двумерного массива на основе большого набора точек xy - PullRequest
2 голосов
/ 07 марта 2019

У меня достаточно большой 1000 x 4000 пикселей xr.DataArray, возвращенный из запроса OpenDataCube , и большой набор (> 200 000) xy значений точек. Мне нужно сэмплировать массив, чтобы он возвращал значение для каждой xy точки и возвращал интерполированные значения (например, если точка находится посередине между 0 и 1.0 пикселем, возвращаемое значение должно быть 0.5).

xr.interp позволяет мне легко выбирать интерполированные значения, но он возвращает огромную матрицу каждой комбинации всех значений x и y, а не только значений для каждой самой точки 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)

Кто-нибудь знает более быстрый или более эффективный способ памяти для достижения этой цели?

1 Ответ

7 голосов
/ 07 марта 2019

Чтобы избежать полной сетки, вам нужно ввести новое измерение.

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 есть хороший пример Расширенная интерполяция .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...