интерполировать данные куба в заданную (список) точку (точки)

Для куба с координатами широта / долгота

surface altitude [m] / (m)          (latitude: 21600; longitude: 43200)
     Dimension coordinates:
          latitude                           x                 -
          longitude                          -                 x
     Attributes:
          Conventions: CF-1.4
          description: GTOPO30 surface elevation dataset
          history: Mon Aug 19 14:04:58 2013: ncrename -v surface altitude,surface_altitude...
          institution: Institute of Environmental Physics, University of Bremen,     Germany.
          label: surface altitude [m]
          least_significant_digit: 4
          source: http://eros.usgs.gov/#/Find_Data/Products_and_Data_Available/gtopo30_i...
          title: Global surface elevation from the GTOPO30

и учитывая список координат широты и долготы, как я могу интерполировать данные куба в заданные точки? (На данный момент подойдет ближайший сосед, но для более грубых кубов подойдут шлицы)

PS: для ближайшего соседа эта интерполяция не должна зависеть от загрузки всего куба в память.


person andreas-h    schedule 19.08.2013    source источник


Ответы (1)


К сожалению, код ближайшего соседа в Iris в настоящее время загружает данные для определения необходимых индексов. Я отправил тривиальный запрос на перенос (усложненный тестированием), чтобы исправить это (https://github.com/SciTools/iris/pull/707), который вы можете попробовать использовать для работы с набором данных такого размера.

Я собираюсь работать с кубом по образцу данных:

import iris
cube = iris.load_cube(iris.sample_data_path('air_temp.pp'))

И я могу проверить, загружены ли данные с помощью следующей функции:

def cube_data_is_loaded(cube):
    # A None data manger means the data is loaded...
    return cube._data_manager is None

So:

>>> print cube_data_is_loaded(cube)
False

По сути, интерфейс (http://scitools.org.uk/iris/docs/latest/iris/iris/analysis/interpolate.html#iris.analysis.interpolate.extract_nearest_neighbour) для ближайшего соседа позволяет выполнить извлечение точки:

from iris.analysis.interpolate import extract_nearest_neighbour
smaller_cube = extract_nearest_neighbour(cube,
                        (('longitude', -180), ('latitude', 1.5)))

>>> print smaller_cube
air_temperature / (K)               (scalar cube)
     Scalar coordinates:
          forecast_period: 6477 hours
          forecast_reference_time: 1998-03-01 03:00:00
          latitude: 2.50002 degrees
          longitude: 180.0 degrees
          pressure: 1000.0 hPa
          time: 1996-12-01 00:00:00
     Attributes:
          STASH: m01s16i203
          source: Data from Met Office Unified Model
     Cell methods:
          mean: time

Обратите внимание, как извлечение на самом деле выбрало ближайшее значение широты к моей запрошенной точке. Одна вещь, которая действительно важна, - это отметить, что эта функция действительно не обрабатывает перенос, если ваша долгота не круговая:

cube.coord('longitude').circular = False
smaller_cube = extract_nearest_neighbour(cube,
                   (('longitude', -180), ('latitude', 1.5)))
cube.coord('longitude').circular = True
>>> print smaller_cube
air_temperature / (K)               (scalar cube)
     Scalar coordinates:
          forecast_period: 6477 hours
          forecast_reference_time: 1998-03-01 03:00:00
          latitude: 2.50002 degrees
          longitude: 0.0 degrees
          pressure: 1000.0 hPa
          time: 1996-12-01 00:00:00, bound=(1994-12-01 00:00:00, 1998-12-01 00:00:00)
     Attributes:
          STASH: m01s16i203
          source: Data from Met Office Unified Model
     Cell methods:
          mean: time

Обратите внимание, как диапазон долготы в исходном кубе (0-360) теперь означает, что ближайшее значение к -180 на самом деле равно 0.

Также существует функция для извлечения траектории (http://scitools.org.uk/iris/docs/latest/iris/iris/analysis/trajectory.html?highlight=trajectory#iris.analysis.trajectory.interpolate):

smaller_traj = interpolate(cube,
                  (('longitude', [-180, -180]), ('latitude', [1.5, 3.5])),
                  'nearest')
>>> print smaller_traj
air_temperature / (K)               (*ANONYMOUS*: 2)
     Auxiliary coordinates:
          latitude                              x
          longitude                             x
     Scalar coordinates:
          forecast_period: 6477 hours
          forecast_reference_time: 1998-03-01 03:00:00
          pressure: 1000.0 hPa
          time: 1996-12-01 00:00:00, bound=(1994-12-01 00:00:00, 1998-12-01 00:00:00)
     Attributes:
          STASH: m01s16i203
          source: Data from Met Office Unified Model
     Cell methods:
          mean: time

Наконец, обратите внимание, что исходные данные куба не были загружены повсюду (с использованием моей ветки), и действительно, данные из small_cube также были отложены:

>>> print cube_data_is_loaded(cube)
False
>>> print cube_data_is_loaded(smaller_cube)
False

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

HTH!

P.S. Мне пока не известны какие-либо алгоритмы сплайн-интерполяции, которые работают с Iris, хотя существует аналогичный интерфейс для линейной интерполяции, если это представляет интерес.

person pelson    schedule 19.08.2013
comment
Спасибо, @pelson, за подробный ответ! Однако мне непонятен ваш комментарий о траекториях, netCDF и индексах. Когда я пробую trajectory.interpolate метод на своем кубе для извлечения четырех точек с помощью nearest, тогда оперативной памяти 4G моего рабочего стола недостаточно, и система начинает подкачку (или мне нужен ваш новейший PR, чтобы воспользоваться этим преимуществом также в интерфейсе траектории? ) - person andreas-h; 20.08.2013
comment
да. Новый PR абсолютно необходим для получения интерполяции без загрузки всех данных. Это было тривиальное, но необходимое изменение, чтобы все работало так, как вам хотелось бы. - person pelson; 20.08.2013