簡體   English   中英

給定 R 中的二維數字“高度圖”矩陣,如何找到所有局部最大值?

[英]Given a 2D numeric "height map" matrix in R, how can I find all local maxima?

我有一個具有非負數值的 R 矩陣。 該矩陣實際上是一個二維高度 map,我想在這個矩陣中找到所有的局部最大值。 對於“平坦”峰,其中相鄰元素彼此相等(並且它們共同是局部最大值),我不在乎會發生什么,只要我在每個“平坦”區域內獲得至少一個坐標。

是否有任何功能可以有效地做到這一點? 顯然,我可以通過手動將循環寫入 go 並單獨測試每個元素,但是在 R 中這樣做會很慢。 我需要對大約一百萬個矩陣執行此操作,每個矩陣平均大約有 884 個元素。

理想情況下,function 將矩陣作為輸入並返回一個 2 列矩陣,其中第 1 列是行坐標,第 2 列是列坐標,矩陣中的每個局部最大值對應一行。

允許矩陣邊緣的局部最大值。 矩陣之外的區域可以被視為具有零高度。

要使用的可重現示例矩陣:

set.seed(5)
msize <- 20 # Change this to whatever you like
x <- matrix(data=abs(rnorm(msize*2)), nrow=msize, ncol=msize)

raster包中的focal()函數是為這樣的計算而設計的。 以下代碼返回所有局部最大值的坐標,包括邊緣上的坐標和屬於“高原”部分的坐標。

library(raster)

## Construct an example matrix
set.seed(444)
msize <- 10
x <- matrix(sample(seq_len(msize), msize^2, replace=TRUE), ncol=msize)

## Convert it to a raster object
r <- raster(x)
extent(r) <- extent(c(0, msize, 0, msize) + 0.5)

## Find the maximum value within the 9-cell neighborhood of each cell
f <- function(X) max(X, na.rm=TRUE)
ww <- matrix(1, nrow=3, ncol=3) ## Weight matrix for cells in moving window
localmax <- focal(r, fun=f, w=ww, pad=TRUE, padValue=NA)

## Does each cell have the maximum value in its neighborhood?
r2 <- r==localmax

## Get x-y coordinates of those cells that are local maxima
maxXY <- xyFromCell(r2, Which(r2==1, cells=TRUE))
head(maxXY)
#       x  y
# [1,]  8 10
# [2,] 10 10
# [3,]  3  9
# [4,]  4  9
# [5,]  1  8
# [6,]  6  8

# Visually inspect the data and the calculated local maxima
plot(r)   ## Plot of heights
windows() ## Open a second plotting device
plot(r2)  ## Plot showing local maxima

如果對角線元素不算作鄰居,你可以很直接地做到這一點。 創建矩陣的 4 個副本,每個副本都朝不同的方向移動,然后在所有四個副本中取平行最大值。 並行最大值為您提供每個元素的最大鄰居的值。 然后,您可以通過測試原始矩陣的每個元素是否大於其所有鄰居來找到最大值:

set.seed(42) 
nrows <- 5
ncols <- 6
x <- matrix(runif(nrows*ncols),nrow=nrows)
#          [,1]      [,2]      [,3]      [,4]       [,5]      [,6]
#[1,] 0.9148060 0.5190959 0.4577418 0.9400145 0.90403139 0.5142118
#[2,] 0.9370754 0.7365883 0.7191123 0.9782264 0.13871017 0.3902035
#[3,] 0.2861395 0.1346666 0.9346722 0.1174874 0.98889173 0.9057381
#[4,] 0.8304476 0.6569923 0.2554288 0.4749971 0.94666823 0.4469696
#[5,] 0.6417455 0.7050648 0.4622928 0.5603327 0.08243756 0.8360043
y <- x>pmax(cbind(x[,-1],0),cbind(0,x[,-ncol(x)]),rbind(x[-1,],0),rbind(0,x[-nrow(x),]))
#      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
#[1,] FALSE FALSE FALSE FALSE FALSE FALSE
#[2,]  TRUE FALSE FALSE  TRUE FALSE FALSE
#[3,] FALSE FALSE  TRUE FALSE  TRUE FALSE
#[4,]  TRUE FALSE FALSE FALSE FALSE FALSE
#[5,] FALSE  TRUE FALSE  TRUE FALSE  TRUE

## recover indices from matrix 
cbind((which(y)-1)%%nrows + 1,
      floor((which(y)-1)/nrows)%%nrows + 1)

#     [,1] [,2]
#[1,]    2    1
#[2,]    4    1
#[3,]    5    2
#[4,]    3    3
#[5,]    2    4
#[6,]    5    4
#[7,]    3    5
#[8,]    5    1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM