Как интерполировать 2D массив из более грубого разрешения в более точное разрешение - PullRequest
0 голосов
/ 20 ноября 2018

Предположим, что у меня есть данные эмиссии с формой (21600,43200), что соответствует lat и lon, т. Е.

lat = np.arange(21600)*(-0.008333333)+90
lon = np.arange(43200)*0.00833333-180

И у меня также есть коэффициент масштабирования с формой (720,1440,7), что соответствует lat, lon, day of week и

lat = np.arange(720)*0.25-90 
lon = np.arange(1440)*0.25-180

Сейчас я хочу применить коэффициент к данным о выбросах и думаю, что мне нужно интерполировать коэффициентна (720,1440) до (21600,43200).После этого я могу умножить интерполированный коэффициент на данные о выбросах, чтобы получить новый выходной сигнал о выбросах.

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

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Если вы просто ищете ближайшего соседа или линейную интерполяцию, вы можете использовать собственный метод xarray da.interp:

scaling_interped = scaling_factor.interp(
    lon=emissions.lon,
    lat=emissions.lat,
    method='nearest')  # or 'linear'

обратите внимание, что это значительно увеличит размермассив.Предполагая, что это 64-разрядные числа с плавающей запятой, результат будет приблизительно (21600*43200*7)*8/(1024**3) или 48.7 GB.Вы можете сократить размер оперативной памяти в 7 раз, разбив массив на день недели и выполнив вычисления вне ядра с помощью dask .

Если вы хотите использовать интерполяциюСхема, отличная от ближайшей или линейной, использует метод , предложенный по тел .

0 голосов
/ 20 ноября 2018

Вот полный пример той интерполяции, которую вы пытаетесь выполнить.В качестве примера я использовал данные emission с формой (10, 20) и данные scale с формой (5, 10).Он использует scipy.interpolate.RectBivariateSpline, который является рекомендуемым методом для интерполяции на обычных сетках:

import scipy.interpolate as sci

def latlon(res):
    return (np.arange(res)*(180/res) - 90,
            np.arange(2*res)*(360/(2*res)) - 180)

lat_fine,lon_fine = latlon(10)
emission = np.ones(10*20).reshape(10,20)

lat_coarse,lon_coarse = latlon(5)
scale = np.linspace(0, .5, num=5).reshape(-1, 1) + np.linspace(0, .5, num=10)

f = sci.RectBivariateSpline(lat_coarse, lon_coarse, scale)
scale_interp = f(lat_em, lon_em)

with np.printoptions(precision=1, suppress=True, linewidth=9999):
    print('original emission data:\n%s\n' % emission)
    print('original scale data:\n%s\n' % scale)
    print('interpolated scale data:\n%s\n' % scale_interp)
    print('scaled emission data:\n%s\n' % (emission*scale_interp))

, который выводит:

original emission data:
[[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]

original scale data:
[[0.  0.1 0.1 0.2 0.2 0.3 0.3 0.4 0.4 0.5]
 [0.1 0.2 0.2 0.3 0.3 0.4 0.5 0.5 0.6 0.6]
 [0.2 0.3 0.4 0.4 0.5 0.5 0.6 0.6 0.7 0.8]
 [0.4 0.4 0.5 0.5 0.6 0.7 0.7 0.8 0.8 0.9]
 [0.5 0.6 0.6 0.7 0.7 0.8 0.8 0.9 0.9 1. ]]

interpolated scale data:
[[0.  0.  0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5]
 [0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6]
 [0.1 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.6]
 [0.2 0.2 0.2 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7]
 [0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.8 0.8]
 [0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.8 0.8 0.8 0.8]
 [0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.8 0.9 0.9]
 [0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 0.9]
 [0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 1.  1.  1. ]
 [0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 1.  1.  1. ]]

scaled emission data:
[[0.  0.  0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5]
 [0.1 0.1 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6]
 [0.1 0.2 0.2 0.2 0.2 0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.6]
 [0.2 0.2 0.2 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7]
 [0.3 0.3 0.3 0.3 0.4 0.4 0.4 0.4 0.5 0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.8 0.8]
 [0.3 0.3 0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.8 0.8 0.8 0.8]
 [0.4 0.4 0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.8 0.9 0.9]
 [0.4 0.5 0.5 0.5 0.5 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 0.9]
 [0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 1.  1.  1. ]
 [0.5 0.5 0.6 0.6 0.6 0.6 0.7 0.7 0.7 0.7 0.8 0.8 0.8 0.9 0.9 0.9 0.9 1.  1.  1. ]]

Примечания

  • Методы интерполяции в scipy.interpolate предполагают строгое увеличение x и y, поэтому вам нужно убедиться, что ваши emission данные расположены в сетке так, что:

    lat = np.arange(21600)*0.008333333 - 90
    

    вместоиз:

    lat = np.arange(21600)*(-0.008333333) + 90
    

    как у вас выше.Вы можете перевернуть ваши emission данные следующим образом:

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