arrays - 3d 数组 R 中的 n 个前邻居列表

标签 arrays r matlab 3d nearest-neighbor

假设我们有一个 3d 数组:

my.array <- array(1:27, dim=c(3,3,3))

我想创建一个包含前 n 个邻居的列表。

示例:让我们得到 my.array[2,2,2]=14,因此 14 的第一个邻居是:

list[14] = [1 to 27] - 14

我还想使用 R、C 或 Matlab 对第二个、第三个、n 个最近的邻居做同样的事情。

谢谢

最佳答案

根据评论,我假设您将“第一最近邻居”定义为欧几里得距离为 1 或以下的所有单元格(不包括自身),“第二最近邻居”为欧几里德距离为 2 或以下的单元格,等等。您的断言在 @evan058's answer 的评论中“对于 (1,1,1),第一级邻居是 2,4,5,10,11,13”,我实际上将其解释为包括直接对角线(距离1.414),但不是进一步的对角线(在您的示例中,14 将是距离为 1.732 的进一步的对角线)。

此函数接受预定义数组 (ary) 或构成一个数组的维度 (dims)。

nearestNeighbors(dims = c(3,3,3), elem = c(1,1,1), dist = 1)
#      dim1 dim2 dim3
# [1,]    2    1    1
# [2,]    1    2    1
# [3,]    1    1    2
nearestNeighbors(dims = c(3,3,3), elem = c(1,1,1), dist = 1,
                 return_indices = FALSE)
# [1]  2  4 10
nearestNeighbors(dims = c(3,3,3), elem = c(1,1,1), dist = 2,
                 return_indices = FALSE)
#  [1]  2  3  4  5  7 10 11 13 14 19

nearestNeighbors(ary = array(27:1, dim = c(3,3,3)), elem = c(1,1,1), dist = 2)
#       dim1 dim2 dim3
#  [1,]    2    1    1
#  [2,]    3    1    1
#  [3,]    1    2    1
#  [4,]    2    2    1
#  [5,]    1    3    1
#  [6,]    1    1    2
#  [7,]    2    1    2
#  [8,]    1    2    2
#  [9,]    2    2    2
# [10,]    1    1    3
nearestNeighbors(ary = array(27:1, dim = c(3,3,3)), elem = c(1,1,1), dist = 2,
                 return_indices = FALSE)
#  [1] 26 25 24 23 21 18 17 15 14  9

功能:

#' Find nearest neighbors.
#'
#' @param ary array
#' @param elem integer vector indicating the indices on array from
#'   which all nearest neighbors will be found; must be the same
#'   length as \code{dims} (or \code{dim(ary)}). Only one of
#'   \code{ary} and \code{dim} needs to be provided.
#' @param dist numeric, the max distance from \code{elem}, not
#'   including the 'self' point.
#' @param dims integer vector indicating the dimensions of the array.
#'   Only one of \code{ary} and \code{dim} needs to be provided.
#' @param return_indices logical, whether to return a matrix of
#'   indices (as many columns as dimensions) or the values from
#'   \code{ary} of the nearest neighbors
#' @return either matrix of indices (one column per dimension) if
#'   \code{return_indices == TRUE}, or the appropriate values in
#'   \code{ary} otherwise.
nearestNeighbors <- function(ary, elem, dist, dims, return_indices = TRUE) {
  if (missing(dims)) dims <- dim(ary)
  tmpary <- array(1:prod(dims), dim = dims)
  if (missing(ary)) ary <- tmpary
  if (length(elem) != length(dims))
      stop("'elem'' needs to have the same dimensions as 'ary'")
  # work on a subset of the whole matrix
  usedims <- mapply(function(el, d) {
    seq(max(1, el - dist), min(d, el + dist))
  }, elem, dims, SIMPLIFY=FALSE)
  df <- as.matrix(do.call('expand.grid', usedims))
  # now, df is only as big as we need to possibly satisfy `dist`
  ndist <- sqrt(apply(df, 1, function(x) sum((x - elem)^2)))
  ret <- df[which(ndist > 0 & ndist <= dist),,drop = FALSE]
  if (return_indices) {
    return(ret)
  } else {
    return(ary[ret])
  }
}

编辑:更改代码以“轻微”提高速度:使用 256x256x256 数组和距离 2 之前在我的机器上花费了约 90 秒。现在只需不到 1 秒。即使距离为 5(同一阵列)也只需不到一秒。 尚未完全测试,请验证其是否正确。

编辑:删除了函数第 50 行多余的 {。

关于arrays - 3d 数组 R 中的 n 个前邻居列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37935323/

相关文章:

c++ - 如何在构造函数中初始化具有相同值的对象数组

php - 如何将多维 PHP 数组转换为 html 表格

r - 快速生成矩阵的笛卡尔积

java - Matlab deploytool 可以编译带有 javax.swing 元素的文件吗?

java 二维数组的索引

c++ - 使用 [] 运算符时为 "binding reference of type discards qualifiers"

r - Tidyverse 获取 lm() 残差的方法,使用列的子集作为预测变量,但将所有内容保留在输出中

r - 在嵌套数据列中引导统计数据并以整齐的格式检索结果

python - 如何绘制应力分布图?

matlab - mex 函数内存泄漏