当前位置: 代码迷 >> python >> R-通过移除x,y和z维的全零2D矩阵来调整3D数组的大小
  详细解决方案

R-通过移除x,y和z维的全零2D矩阵来调整3D数组的大小

热度:96   发布时间:2023-06-13 13:58:07.0

R,Python,Lua,Java,Matlab或任何编程语言中是否有任何函数可以通过删除全零来将3D input_array的大小从c(6,6,6)减小到c(4,4,4)矩阵在3维的外围?

## Create an empty array with all zeros
input_array <- array(data = c(0), dim = c(6, 6, 6)) 

## Populate the central locations of the array with 1
input_array[, ,2:5] <- matrix(c(0, 0, 0, 0, 0, 0, 
                                0, 1, 1, 1, 1, 0,  
                                0, 1, 1, 1, 1, 0, 
                                0, 1, 1, 1, 1, 0, 
                                0, 1, 1, 1, 1, 0, 
                                0, 0, 0, 0, 0, 0), 
                                nrow = 6, ncol = 6) 

## Show the input_array
input_array 

## The target output
output_array <- array(data = c(1), dim = c(4, 4, 4)) 

因此,换句话说,我正在寻找一个将input_array用作输入并将output_array用作输出的函数。 我想在整个转换过程中保持阵列的3D性质。 我要研究的原因是,我有非常大的3D数组,外围有很多零,并且通过从三个维度中删除全零矩阵,我可以实现这些数组大小的显着减少,因此允许以提高处理效率。

如果那里没有函数,那么编写一个新函数以完成此任务的逻辑是什么? 如果您有任何可分享的内容,请使用您喜欢的任何语言,非常感谢您提供任何反馈或帮助。

借助abind包,您可以在R中做得相当好,这对于处理数组非常方便:

abind::asub(input_array,    # take this and subset
            lapply(1:3, function(d){    # iterate over its dimensions
                apply(input_array != 0, d, any)    # look for any non-zero elements
            }))
## , , 1
## 
##      [,1] [,2] [,3] [,4]
## [1,]    1    1    1    1
## [2,]    1    1    1    1
## [3,]    1    1    1    1
## [4,]    1    1    1    1
## 
## , , 2
## 
##      [,1] [,2] [,3] [,4]
## [1,]    1    1    1    1
## [2,]    1    1    1    1
## [3,]    1    1    1    1
## [4,]    1    1    1    1
## 
## , , 3
## 
##      [,1] [,2] [,3] [,4]
## [1,]    1    1    1    1
## [2,]    1    1    1    1
## [3,]    1    1    1    1
## [4,]    1    1    1    1
## 
## , , 4
## 
##      [,1] [,2] [,3] [,4]
## [1,]    1    1    1    1
## [2,]    1    1    1    1
## [3,]    1    1    1    1
## [4,]    1    1    1    1

感谢所有分享想法或引用其他类似文章的人。 我通过您的答案达到了这一点:

## Create an empty array with all zeros
input_array <- array(data = c(0), dim = c(6, 6, 6)) 

## Populate the central locations of the array with 1
input_array[, ,2:5] <- matrix(c(0, 0, 0, 0, 0, 0, 
                                0, 1, 1, 1, 1, 0,  
                                0, 1, 1, 1, 1, 0, 
                                0, 1, 1, 1, 1, 0, 
                                0, 1, 1, 1, 1, 0, 
                                0, 0, 0, 0, 0, 0), 
                                nrow = 6, ncol = 6) 

## Show the input_array
input_array 

## The target output
(output_array <- input_array[apply(input_array != 0, 3, any),
                             apply(input_array != 0, 2, any),
                             apply(input_array != 0, 1, any)])  

我没有用不同的输入进行测试,因此可能需要对不同的输入进行进一步的测试。

这是一个选项( python / numpy ):

xcrit = np.where(np.any(input, axis=(0,1)))[0]
ycrit = np.where(np.any(input, axis=(0,2)))[0]
zcrit = np.where(np.any(input, axis=(1,2)))[0]
output = input[zcrit[0]:zcrit[-1]+1,ycrit[0]:ycrit[-1]+1,xcrit[0]:xcrit[-1]+1]

说明如果沿着传递的维度至少一个单元格为True,则np.any返回True。 它返回一个形状类似于其余维度的布尔数组

np.where查找其参数的True单元的索引。 在此示例中,我们使用它来查找沿每个坐标的第一个和最后一个非零切片的索引

样品运行:

>>> input = np.zeros((6,6,6))
>>> input[1:-2,1:-2,2:-1] = 1
>>> xcrit = np.where(np.any(input, axis=(0,1)))[0]
>>> ycrit = np.where(np.any(input, axis=(0,2)))[0]
>>> zcrit = np.where(np.any(input, axis=(1,2)))[0]
>>> output = input[zcrit[0]:zcrit[-1]+1,ycrit[0]:ycrit[-1]+1,xcrit[0]:xcrit[-1]+1]
>>> # verify
... input.sum(), output.sum(), output.size
(27.0, 27.0, 27)
  相关解决方案