计算矩阵中每个元素的最近邻标准偏差的有效方法
Efficient way to compute standard deviation of nearest neighbours of each element in matrix
我想计算矩阵中每个元素的最近邻(3*3 移动 window)的标准差。我在 R 中写了一些代码来实现它:
library(FNN)
df <- matrix(1:10000, nrow = 100, ncol = 100, byrow = TRUE)
df_ <- reshape2::melt(df)
df_index <- df_[, c(1,2)]
df_query <- df_index
neighbor_index <- knnx.index(df_index, df_query, k = 9, algorithm = 'kd_tree')
neighbor_coor<- apply(neighbor_index, 1, function(x) df_query[x, ])
neighbor_sd <- lapply(neighbor_coor, function(x) sd(df[x[, 1], x[, 2]]))
sd <- do.call(rbind, neighbor_sd)
但是速度太慢了。你能给我一些加速的建议吗?还有其他方法可以实现吗?
正如@romanlustrik 在他的评论中提出的那样,我们可以使用 raster::focal()
来解决这个问题。
library(raster)
df <- matrix(1:10000, nrow = 100, ncol = 100, byrow = TRUE)
dfR <- raster(df)
dfSD <- as.matrix(focal(dfR, w = matrix(1,3,3), fun = sd))
其中,w
是表示最近邻及其在 fun
内的权重的矩阵(在本例中为 3x3,即单元本身及其 8 个邻居)。因此,只要可以用矩阵表示,任何邻域模式都是可以想象的。
matrix(1,3,3)
# [,1] [,2] [,3]
# [1,] 1 1 1
# [2,] 1 1 1
# [3,] 1 1 1
只有 4 个邻居(不包括对角线和单元格本身)的示例:
matrix(c(0,1,0,1,0,1,0,1,0), 3, 3)
# [,1] [,2] [,3]
# [1,] 0 1 0
# [2,] 1 0 1
# [3,] 0 1 0
我想计算矩阵中每个元素的最近邻(3*3 移动 window)的标准差。我在 R 中写了一些代码来实现它:
library(FNN)
df <- matrix(1:10000, nrow = 100, ncol = 100, byrow = TRUE)
df_ <- reshape2::melt(df)
df_index <- df_[, c(1,2)]
df_query <- df_index
neighbor_index <- knnx.index(df_index, df_query, k = 9, algorithm = 'kd_tree')
neighbor_coor<- apply(neighbor_index, 1, function(x) df_query[x, ])
neighbor_sd <- lapply(neighbor_coor, function(x) sd(df[x[, 1], x[, 2]]))
sd <- do.call(rbind, neighbor_sd)
但是速度太慢了。你能给我一些加速的建议吗?还有其他方法可以实现吗?
正如@romanlustrik 在他的评论中提出的那样,我们可以使用 raster::focal()
来解决这个问题。
library(raster)
df <- matrix(1:10000, nrow = 100, ncol = 100, byrow = TRUE)
dfR <- raster(df)
dfSD <- as.matrix(focal(dfR, w = matrix(1,3,3), fun = sd))
其中,w
是表示最近邻及其在 fun
内的权重的矩阵(在本例中为 3x3,即单元本身及其 8 个邻居)。因此,只要可以用矩阵表示,任何邻域模式都是可以想象的。
matrix(1,3,3)
# [,1] [,2] [,3]
# [1,] 1 1 1
# [2,] 1 1 1
# [3,] 1 1 1
只有 4 个邻居(不包括对角线和单元格本身)的示例:
matrix(c(0,1,0,1,0,1,0,1,0), 3, 3)
# [,1] [,2] [,3]
# [1,] 0 1 0
# [2,] 1 0 1
# [3,] 0 1 0