Умножение двух растров с разными размерами ячеек в R

Я хочу умножить изображение Landsat с разрешением 30 м на растр ERA5 с разрешением около 25 км. Я могу уменьшить масштаб ERA5 до 30 м, но это увеличит обработку. Мне просто интересно, возможно ли, что какие бы 30-метровые ячейки ни пересекались с ячейкой 25 км, эти 30-метровые ячейки умножаются на одно значение из ячейки 25 км.

library(terra)
### 1st raster
ETrF <- rast(ncols=4, nrows=4, xmin=73, xmax=75, ymin=31, ymax=33)
### 2nd raster
ET0 <- rast(ncols=2, nrows=2, xmin=73, xmax=75, ymin=31, ymax=33)
### Random values assigned to both rasters
values(ETrF) <- c(0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8)
values(ET0) <- c(5,1,2,4)

### Now 1st cell of ET0 (value: 5) will overlap with 1st,2nd,5th and 6th cells (values: 0.1,0.2,0.5,0.6) 
### of ETrF.Is it possible that 5 gets multiplied with 0.1,0.2,0.5 and 0.6 and final output 
### keeps ETrFs resolution.

ETa <- ETrF*ET0.....?

Не эксперт, но читали ли вы документацию raster::resample? Сделал бы (ET0v1 = raster::resample(ET0, ETrF)); ETa = ETrF * ET0v1; par(mfrow = c(1L, 3L)); X = lapply(list(ETrF, ET0, ETa), plot) (или в другом порядке) то, что вам нужно?

Friede 17.04.2024 13:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
102
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я считаю, что resample — это правильный путь, возможно, использование аргумента threads может повысить эффективность.

Альтернативным решением было бы извлечение значений из ET0 с использованием центроидов из ETrF, но трудно сказать, насколько это повысит эффективность. Мне пришлось бы сравнить его с большим набором данных.

Вот возможный подход с использованием данных вашего примера.

library(terra)
library(sf)
library(dplyr)

ETrF_c <- st_as_sf(as.points(ETrF, values = TRUE)) # ETrF centroids

ETrF_new <- st_as_sf(extract(ET0, ETrF_c, bind = TRUE)) %>% 
  mutate(value = lyr.1*lyr.1.1) %>% 
  rasterize(., ETrF, field = 'value')

plot(ETrF_new)

И тебе спасибо. Ваше решение работает очень хорошо. Я высоко ценю быстрый ответ и ваши усилия.

Waqas Ahmad 25.04.2024 08:45

Поскольку все согласны с resample(), с моей точки зрения, это должно быть частью ответа, поэтому вот небольшой демонстратор, использующий {terra}:

ET0_resampled <- resample(ET0, ETrF)
ET0_resampled
#> class       : SpatRaster 
#> dimensions  : 4, 4, 1  (nrow, ncol, nlyr)
#> resolution  : 0.5, 0.5  (x, y)
#> extent      : 73, 75, 31, 33  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (CRS84) (OGC:CRS84) 
#> source(s)   : memory
#> name        : lyr.1 
#> min value   :     1 
#> max value   :     5

ET0_resampled * ETrF
#> class       : SpatRaster 
#> dimensions  : 4, 4, 1  (nrow, ncol, nlyr)
#> resolution  : 0.5, 0.5  (x, y)
#> extent      : 73, 75, 31, 33  (xmin, xmax, ymin, ymax)
#> coord. ref. : lon/lat WGS 84 (CRS84) (OGC:CRS84) 
#> source(s)   : memory
#> name        : lyr.1 
#> min value   : 0.275 
#> max value   : 3.200

С точки зрения производительности я не могу рекомендовать использовать подход «извлечение-мутация-растрирование» — каким бы креативным он ни был:

extract_mutate_rasterize <- function(coarse, fine) {
  
  # centroids
  fine_c <- as.points(fine, values = TRUE) %>% st_as_sf()
  
  res <- extract(coarse, fine_c, bind = TRUE) %>% 
    st_as_sf() %>% 
    mutate(value = lyr.1 * lyr.1.1) %>% 
    rasterize(., fine, field = 'value')
  
  res
}

microbenchmark::microbenchmark("terra::resample(threads = TRUE)" = terra::resample(ET0, ETrF, threads = TRUE) * ETrF,
                               "extract_mutate_rasterize @ FAmorim" = extract_mutate_rasterize(ET0, ETrF),
                                times = 500)
#> Unit: milliseconds
#>                                expr     min       lq      mean  median       uq
#>     terra::resample(threads = TRUE)  5.9338  6.40875  7.625009  7.1113  8.21190
#>  extract_mutate_rasterize @ FAmorim 36.2193 41.15560 47.067254 45.7299 50.00195
#>       max neval
#>   21.1489   500
#>  157.1793   500

... и я действительно не могу себе представить, чтобы это хорошо масштабировалось с увеличением количества ячеек.

Ответ принят как подходящий

Причина, по которой это не реализовано, заключается в том, что вам нужно выбрать способ повторной выборки данных; x * y не могу это уловить.

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

Но он не дает тех же результатов, что и метод извлечения. (для этого нужно использовать resample( , method = "near")). С данными игрушки вы также можете использовать disagg.

Если вы хотите использовать маршрут извлечения, это можно сделать намного эффективнее, избегая приведения к sf, по крайней мере, в этом игрушечном примере:

fastextr <- function(coarse, fine, method = "simple") {
    xy <- crds(fine)
    value <- extract(coarse, xy, method=method) * values(fine)
    rasterize(xy, fine, value)
}

microbenchmark::microbenchmark(
    "res" = terra::resample(ET0, ETrF, "near", threads = TRUE) * ETrF,
    "mutat" = extract_mutate_rasterize(ET0, ETrF),
    "disagg" = terra::disagg(ET0, 2) * ETrF,
    "fextr" = fastextr(ET0, ETrF), 
    times = 50
) 

#Unit: milliseconds
#   expr     min      lq      mean   median      uq     max neval
#    res  6.2586  6.4362  6.948614  6.67490  6.8020 21.1767    50
#  mutat 38.6304 39.4301 40.627638 40.08070 41.1208 58.3876    50
# disagg  4.5824  4.6490  5.158002  4.77420  4.9126 21.7821    50
#  fextr  7.9329  8.1154  8.468164  8.44225  8.6150 11.1409    50

Поэтому лучший вариант — использовать билинейную передискретизацию.

bres <- terra::resample(ET0, ETrF, "bilinear", threads = TRUE) * ETrF

Тот же результат можно получить с помощью билинейного экстракта

bextr <- fastextr(ET0, ETrF, "bilinear")

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

Спасибо за указание, что method = "bilinear" будет использоваться по умолчанию при использовании project() здесь, и поэтому результат будет отличаться от extract_mutate_rasterize().

dimfalk 19.04.2024 09:23

Спасибо, что указали на использование crds, так как это намного эффективнее!

FAmorim 23.04.2024 13:06

Большое спасибо. Я пытаюсь использовать ETrF модели METRIC в качестве коэффициента обрезки (Kc) и умножить его на эталонное ET, чтобы получить фактическое ET. Проблема: у меня нет доступа к данным наблюдений за погодой, поэтому я подумал вместо этого использовать данные климатических моделей. Да, вероятно, лучше всего использовать повторную выборку с использованием подхода ближайшего соседа, поскольку он сохраняет исходное значение ячейки для всех уменьшенных ячеек в этой области. Я избегаю дополнительной обработки, иначе я знаю, что могу уменьшить масштаб климатических данных в ArcGIS, используя криггинг и DEM в качестве копеременных.

Waqas Ahmad 24.04.2024 12:17

Вы также можете сделать это в R. Смотри terra::interpolate

Robert Hijmans 24.04.2024 21:36

Другие вопросы по теме

R terra эквивалент растра::overlay с функцией двух растров - медленнее с большими растрами?
Заменить все значения ячеек в растре из обновленных совокупных значений полигонов (т. е. обновить оценки численности населения, привязанные к сетке)
Код Python для поиска широты и долготы в файле формы
Пользовательский тип SQL Alchemy, принудительный параметр привязки больших двоичных объектов
Geopandas не возвращает правильный буфер в метрах
Как выбрать все группы пересекающихся полигонов из одной таблицы с помощью PostGIS
R — обновить значения растра, попадающие внутрь многоугольника
St_join недостаточно точен для определения того, находится ли точка внутри многоугольника
Создайте ограничивающую рамку SF из четырех координат широты и долготы
Как присвоить значение многоугольника существующим внутри него черепахам с помощью ГИС-расширения NetLogo?