按行填充多维数组 [英] Fill multidimensional array by row
问题描述
在提出问题之前,我将指出在此处但是该线程并不能真正回答我的问题.
Before presenting the question, I will point out that something similar was asked here but that this thread doesn't really answer my question.
请考虑以下维数组:
1D: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
2D: [[1,2,3,4,5,6,7,8], [9,10,11,12,13,14,15,16]]
3D: [[[1,2,3,4],[5,6,7,8]], [[9,10,11,12],[13,14,15,16]]]
4D: [[[[1,2],[3,4]], [[5,6],[7,8]], [[[9,10],[11,12]], [[13,14],[15,16]]]]
...
- 一维数组的长度为16
- 2D数组是2x8
- 3D数组是2x2x4
- 4D数组是2x2x2x2
- The 1D array is length 16
- The 2D array is 2x8
- The 3D array is 2x2x4
- The 4D array is 2x2x2x2
假设我要创建数组.对于前两个,我可以在R
Suppose I want to create the arrays. For the first two, I could do something like this in R
oneD <- array(1:16, dim=16) # class(oneD) = array
twoD <- array(1:16, dim=8) # class(twoD) = matrix
但是,twoD数组现在表示为
However, the twoD array is now represented as
[[1,3,5,7,9,11,13,15], [2,4,6,8,10,12,14,16]]
我知道有两种解决方法.
I am aware of two ways around this.
twoD <- aperm(array(1:16, dim=8))
twoD <- matrix(1:16, nrow=2, byrow=TRUE)
但是,这些方法不适用于填充3D和4D阵列.我在下面填入它们,但我希望它们与上面的定义匹配.
However, these methods won't work for filling the 3D and 4D arrays. I fill them below, but I would like them to match my definitions above.
threeD <- array(1:16, dim=c(2,2,4)) # class(threeD) = array
fourD <- array(1:16, dim=c(2,2,2,2)) # class(fourD) = array
编辑
bgoldst的回答使我意识到,事实上,精子确实可以满足我的需求.
bgoldst's answer made me realize that in fact aperm does work for what I want.
threeD <- aperm(array(1:16, dim=c(2,2,4))
# threeD[1,1,1] = 1
# threeD[1,1,2] = 2
# threeD[1,2,1] = 3
# threeD[1,2,2] = 4
# threeD[2,1,1] = 5
# ....
推荐答案
在编写数据时,需要先在最深的维度上填充数组,然后再在较浅的维度上填充数组.这与R通常填充矩阵/数组的方式相反.
The way you've written your data, you need to fill your arrays across the deepest dimension first, and then across shallower dimensions. This is the opposite of the way R normally fills matrices/arrays.
还应该说,这与仅按行填充 略有不同.为了使用3D数组对此进行说明,您已经表明它需要4个z切片,并且最里面的子数组"的长度为4.这意味着您需要先填充z切片,然后填充列,然后填充行.这不仅是按行填充,而且按最深的维度填充到最浅的维度(如果愿意,也可以按最大到最小填充).诚然,这个概念通常被称为按行"或主要行",但是我不在乎那些术语,因为它们太二维,并且它们也误导了IMO,因为考虑到了行成为最浅的维度.
It also needs to be said that this is slightly different from simply filling by row. To use your 3D array as an illustration of this, you've indicated it requires 4 z-slices, and the innermost "subarrays" have length 4. This means you need to fill across z-slices first, then across columns, then across rows. This is not merely filling by row, but by deepest dimension to shallowest dimension (or greatest to least, if you prefer). Admittedly, this concept is often referred to as "by row" or "row-major order", but I don't care for those terms, since they're too 2D, and they're also misleading IMO, since rows are considered to be the shallowest dimension.
详细说明:最好将填充顺序认为是跨 个维度,而不是沿个维度.考虑一个 r × c × z 立方体.如果您面对的是立方体的前部(即,面对由 z = 1形成的 r × c 矩阵),将 along 行 r = 1移动,也就是说,沿着顶部的行从左向右移动,然后您也将 along (或 within ).z切片 z =1.沿尺寸方向移动的想法无济于事.但是,如果您认为这样的从左到右的移动跨过 列,那么这是完全明确的.因此,跨行表示上下,跨栏表示左右,而z切片表示前后.对此的另一种思考方式是,每个运动都是沿着轴"方向进行的,尽管我通常不喜欢这种方式,因为这时您必须引入轴的概念.无论如何,这就是为什么我不在乎术语按行"和行主要顺序"(以及类似的列主要顺序"),因为思考该运动(IMO)的正确方法是跨列(二维),或跨最深的维度(随后是较浅的维度)以获得更高的维度.
To elaborate: It's better to think of fill order as being across dimensions rather than along dimensions. Think of an r×c×z cube. If you're facing the front of the cube (that is, facing the r×c matrix formed from z = 1), if you move along row r = 1, that is, from left to right along the top row, then you're also moving along (or within) z-slice z = 1. The idea of moving along a dimension is not helpful. But if you think of such left-to-right movement as being across columns, then that is completely unambiguous. Thus, across rows means up-down, across columns means left-right, and across z-slices means front-back. Another way of thinking about this is each respective movement is along the dimension "axis", although I don't usually like to think of it that way, because then you have to introduce the idea of axes. Anyway, this is why I don't care for the terms "by row" and "row-major order" (and similarly "column-major order"), since the proper way to think about that movement (IMO) is across columns for 2D, or across the deepest dimension (followed by shallower dimensions) for higher dimensionalities.
您可以通过首先构建具有反向维数的数组,然后将其转置为反向"(?)维数来实现此要求.这将根据需要布置数据.当然,对于1D,不需要转置,对于2D,我们可以使用 aperm()
.并且方便地,当您在不指定perm
参数的情况下调用aperm()
时,默认情况下,它将反转输入的维数.就像调用t()
.
You can achieve the requirement by first building the arrays with reversed dimensionality, and then transposing them to "dereverse" (?) the dimensionality. This will lay out the data as you need. Of course, for 1D, no transposition is necessary, and for 2D we can just use t()
, but for higher dimensionalities we'll need aperm()
. And conveniently, when you call aperm()
without specifying the perm
argument, by default it reverses the dimensionality of the input; this is just like calling t()
.
array(1:16,16);
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
t(array(1:16,c(8,2))); ## alternatives: matrix(1:16,2,byrow=T), aperm(array(1:16,c(8,2)))
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,] 1 2 3 4 5 6 7 8
## [2,] 9 10 11 12 13 14 15 16
aperm(array(1:16,c(4,2,2))); ## same as aperm(array(1:16,c(4,2,2)),3:1)
## , , 1
##
## [,1] [,2]
## [1,] 1 5
## [2,] 9 13
##
## , , 2
##
## [,1] [,2]
## [1,] 2 6
## [2,] 10 14
##
## , , 3
##
## [,1] [,2]
## [1,] 3 7
## [2,] 11 15
##
## , , 4
##
## [,1] [,2]
## [1,] 4 8
## [2,] 12 16
##
aperm(array(1:16,c(2,2,2,2))); ## same as aperm(array(1:16,c(4,2,2)),4:1)
## , , 1, 1
##
## [,1] [,2]
## [1,] 1 5
## [2,] 9 13
##
## , , 2, 1
##
## [,1] [,2]
## [1,] 3 7
## [2,] 11 15
##
## , , 1, 2
##
## [,1] [,2]
## [1,] 2 6
## [2,] 10 14
##
## , , 2, 2
##
## [,1] [,2]
## [1,] 4 8
## [2,] 12 16
##
这篇关于按行填充多维数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!