如何对具有m*(n-i)维矩阵的n维数组进行切片? [英] How to slice a n dimensional array with a m*(n-i) dimensional matrix?

查看:31
本文介绍了如何对具有m*(n-i)维矩阵的n维数组进行切片?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有一个n维数组,它可以被m*n矩阵切片,如下

a <- array(1:27,c(3,3,3))

b <- matrix(rep(1:3,3),3)

# This will return the index a[1,1,1] a[2,2,2] and a[3,3,3]
a[b]

# Output
[1]  1 14 27

有没有什么"有效而简单"的方法来做类似的切片,而不是保留一些维度? 即用m(n-i)(n-i)维数组对n维数组进行切片 获取i+1维数组作为结果。

a <- array(1:27,c(3,3,3))

b <- matrix(rep(1:2,2),2)

# This will return a vector of the index a[1] a[2] a[1] and a[2]
a[b]

# Output
[1] 1 2 1 2


# This will return the indexes of the cartesian product between the vectors,
# that is a array consisting of a[1,,1] a[1,,2] a[2,,1] and a[2,,2]
a[c(1,2),,c(1,2)]

# Output
, , 1

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

, , 2

     [,1] [,2] [,3]
[1,]   10   13   16
[2,]   11   14   17
所需的结果应该是最后一个命令返回数组 带有[1,,1]和[2,,2]。 目前,我使用for循环和abind解决了这个问题,但我相信一定有更好的方法。

# Desired functionality
a <- array(1:27,c(3,3,3))
b <- array(c(c(1,2),c(1,2)),c(2,2))
sliceem(a,b,freeDimension=2)

# Desired output (In this case rbind(a[1,,1],a[2,,2]) ) 
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]   11   14   17

推荐答案

我认为这是最干净的方法--创建一个单独的函数:

slicem <- function(a,idx,drop=FALSE) do.call(`[`,c(list(a),idx,list(drop=drop)))

# usage for OP's example
a      <- array(1:27, c(3,3,3))    
idx    <- list(1:2, TRUE, 1:2)
slicem(a,idx)

这给了

, , 1

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

, , 2

     [,1] [,2] [,3]
[1,]   10   13   16
[2,]   11   14   17

您必须为不从中选择的每个维度编写TRUE


遵循操作员的新期望...

library(abind)
nistfun <- function(a,list_o_idx,drop=FALSE){
  lens <- lengths(list_o_idx)
  do.call(abind, lapply(seq.int(max(lens)), function(i)
    slicem(a, mapply(`[`, list_o_idx, pmin(lens,i), SIMPLIFY=FALSE), drop=drop)
  ))
}

# usage for OP's new example
nistfun(a, idx)

# , , 1
# 
#      [,1] [,2] [,3]
# [1,]    1    4    7
# 
# , , 2
# 
#      [,1] [,2] [,3]
# [1,]   11   14   17

现在,任何非TRUE索引必须具有相同的长度,因为它们将被匹配。

这里使用abind而不是rbind(请参阅关于此答案的早期编辑),因为这是考虑对数组进行切片的唯一合理的一般方法。如果您真的想删除维度,那么应该删除哪些维度以及如何删除非常不明确,因此只返回向量:

nistfun(a, idx, drop=TRUE)
# [1]  1  4  7 11 14 17

如果您想要将它放回某种类型的数组中,可以在事后执行此操作:

matrix( nistfun(a, idx), max(lengths(idx)), dim(a)[sapply(idx,isTRUE)]), byrow=TRUE)

#      [,1] [,2] [,3]
# [1,]    1    4    7
# [2,]   11   14   17

这篇关于如何对具有m*(n-i)维矩阵的n维数组进行切片?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆