Julia:如何将向量转换为多个 m x n 矩阵而无需循环?

5
假设我有一个向量 V,我想将这个向量转换成多个 m x n 矩阵,或者从这个向量 V 获取多个 m x n 矩阵。最基本的例子是:将 V = collect(1:75) 转换为 3 个 5x5 矩阵。
据我所知,可以通过首先使用 reshape reshape(V, 5, :),然后循环遍历它来完成此操作。在 Julia 中是否有更好的方法而不使用循环?
如果可能,最好能够轻松地在行主序和列主序结果之间进行更改的解决方案。

1
你想要将这3个矩阵“分块”(reshape(1:25, ...)等)还是跨步(strided)?collect(eachslice(reshape(V, 3,5, 5), dims = 1))可以得到所需的形状,但可能不是你想要的。 - phipsgabler
1
你能解释一下为什么你不想要一个循环吗?就我个人而言,我通常认为循环是表达这些转换最易读的形式。 - Nils Gudat
1
我对要求行优先结果的内容很感兴趣,实际上我从未使用过行优先数组,并且在快速搜索中也找不到任何有用的信息。我猜测transpose可以将列优先的数组转换为表示行优先数组的视图,但这并不等同于直接生成一个行优先数组。 - BatWannaBe
1
@phipsgabler 不应该是collect(eachslice(reshape(V, 5,5,:); dims=3))吗? - DNF
也许,dims参数总是让我感到困惑... - phipsgabler
@NilsGudat 我的理解是,用Julia应该可以做到这一点,而不是我想在所有情况下避免循环。结果 reshape(V, 5, 5, :) 基本上就是我想要的。我在 @NaphatAmundsen 的回答下发了一些后续问题。此外,transposepermutedims 有什么区别(我迄今为止都是用它们来在列主序和行主序之间切换)? - Jessica Nowak
1个回答

2
TL:DR
总结:
m, n, n_matrices = 4, 2, 5
V = collect(1:m*n*n_matrices)
V = reshape(V, m, n, :)
V = permutedims(V, [2,1,3])
display(V)

根据我对Julia的有限了解:

当执行V = collect(1:m*n)时,您会在内存中初始化一个连续的数组。从V,您希望创建一个mn的矩阵容器。您可以通过执行reshape(V, m, n, :)来实现这一点,然后可以使用V[:,:,1]访问第一个矩阵。在这种情况下,“容器”只是另一个数组(因此您有一个三维数组),我们在这种情况下将其解释为“矩阵数组”(但您也可以将其解释为盒子)。然后,您可以通过交换前两个维度来转置数组中的每个矩阵,如下所示:permutedims(V, [2,1,3])

工作原理

据我所知,在Julia中,当您没有进行任何“跳过”(例如V[1:2:end])时,n维数组是内存中的连续数组。例如,2 x 4矩阵A

1 3 5 7
2 4 6 8

在内存中是这样的 1 2 3 4 5 6 7 8。您只需要以特定方式解释数据,其中前两个数字组成第一列,然后第二个两个数字组成下一列,等等。函数reshape只是简单地指定您希望如何解释内存中的数据。因此,如果我们执行reshape(A, 4, 2),我们基本上将内存中的数字解释为“前四个值组成第一列,第二个四个值组成第二列”,我们将得到:

1 5
2 6
3 7
4 8

我们基本上在这里做的是相同的事情,只不过多了一个维度。
从我的观察来看,在这种情况下,permutedims 似乎也会重新分配内存。如果我错了,请随时纠正我。
旧答案:
我对Julia不太了解,但是在Python中使用NumPy,我会这样做:
reshape(V, :, m, n)

编辑:如@BatWannaBe所述,结果在技术上是一个数组(但是三维的)。您始终可以将三维数组解释为2D数组的容器,这是我理解您所要求的内容。

1
从技术角度来看,reshape(1:75, :, 5, 5) 可以创建一个3x5x5的ReshapedArray,但我相信这不是OP想要的。要创建3个独立的5x5实例,必须在某个层面上进行循环。 - BatWannaBe
1
是的,我理解OP想要一个可迭代的(m, n)大小的数组。至少对于NumPy来说,一个简单的解决方案就像我的答案中所述。 - Naphat Amundsen
我在Julia中尝试了一下,不得不转一下,V = reshape(V, 5, 5, :) 看起来很有前途。之后我可以用 V[:, :, 1]V[:, :, 2] 等来引用它们。 以下是几个问题:
  • 这是为什么会起作用呢?
  • 如果我有一个单矩阵 A,从 reshape 中获得的结果,我可以使用 permutedims(A) 来切换到“行优先”,是否可能通过某种方式一次性将其应用到从 reshape(V, 5, 5, :) 得到的所有矩阵上?
- Jessica Nowak
1
@JessicaNowak 你好。我终于有时间尝试使用Julia了,现在我已经更新了我的答案以回答你的额外问题。 - Naphat Amundsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接