【发布时间】:2019-04-08 20:00:07
【问题描述】:
在 Python 和 MATLAB 中,您都可以使用名为 reshape() 的函数来更改矩阵的维度。
这是线性代数中的什么运算,是基的变化,还是更简单的矩阵乘法,或者两者都不是?
【问题讨论】:
-
您查看过
reshape文档 (MATLAB) 中的示例吗?
标签: python matlab matrix reshape
在 Python 和 MATLAB 中,您都可以使用名为 reshape() 的函数来更改矩阵的维度。
这是线性代数中的什么运算,是基的变化,还是更简单的矩阵乘法,或者两者都不是?
【问题讨论】:
reshape 文档 (MATLAB) 中的示例吗?
标签: python matlab matrix reshape
这个函数与线性代数无关,它是一个简单的索引技巧。考虑以下情况(我将使用 MATLAB syntax,但在 Python 中,尤其是使用 NumPy/SciPy,它的功能相同):
A = [1 2 3; 4 5 6]; % 2-by-3 matrix
B = reshape(A,3,2); % B is 3-by-2
B =
1 5
4 3
2 6
所以实际上您在A 中有 6 个索引:1 到 6,按列优先顺序排列。重塑时,线性样式保持不变,只是重新排序。线性地,您的元素按升序排列:1 4 2 5 3 6,它们存储在连续的内存中。各种各样的“标题”告诉程序这些连续元素是如何形成的。这就是为什么reshape 几乎是免费的:它只会更改标题。
线性代数与此无关,这只是使某些编程任务更容易的数字技巧。
有关 MATLAB 中的索引如何工作的更多信息,我推荐this great Q/A。
在底层,MATLAB 使用sub2ind() 将A(2,2) 转换为A(4),即第四个线性索引,正是因为所有内容都存储为线性向量。重塑所做的一切就是告诉头部元素 3 不再位于 A(1,2),而是更改为 A(3,1),因为它的外观发生了变化。
【讨论】:
A 的转置将是 [1 4; 2 5; 3 6],这是与转置矩阵不同的矩阵。转置改变了元素的顺序,因此它比简单的重塑更昂贵
reshape 的文档,Adriaan 链接了该文档,以及 this other documentation page。
reshape 是微不足道的,没有数据被复制,并且转置需要相当长的时间,它确实复制了数据。
【讨论】:
You can think of reshaping as first raveling the array [...] then inserting [...] using the same kind of index。因此,如果它们是原生线性存储的,那听起来很琐碎。
您可以重塑的最简单的矩阵是 2x2,但您会明白的。 (抱歉,StackOverflow 不允许我插入图像或 LaTex,因此,您需要忍受一些才能阅读此内容。)
我们从A=[[a,b],[c,d]] 开始,我们希望将其重塑为一个 1x4 数组:[[a,b,c,d]]。你可以用代数方式做到这一点:
[[1,0]] * A * [[1,0,0,0],[0,0,0,0]] +
[[1,0]] * A * [[0,0,0,0],[0,1,0,0]] +
[[0,1]] * A * [[0,0,1,0],[0,0,0,0]] +
[[0,1]] * A * [[0,0,0,0],[0,0,0,1]]
* 表示矩阵乘法。
每个术语都是一致矩阵的乘积:1x2 * 2x2 * 2x4,它为您提供形状 1x4 的结果。
第一个学期给你[[a,0,0,0]],第二个[[0,b,0,0]],第三个[[0,0,c,0]]和第四个[[0,0,0,d]]。
将其推广到任意形状 nxm 的 A 应该不会太难。您将需要 n*m 术语而不是 4,因为您的重构矩阵将是 1x(n*m)。每个术语都需要是一致的,因此,您需要一个形状为 1xn 的矩阵来从左侧命中 A,并需要一个形状为 mx(n*m) 的矩阵来从右侧命中 A。
如果您需要将形状 nxm 的 A 重塑为形状 kxl,其中 k*l=n*m,您需要使用 kxn 矩阵从左侧击中 A,并使用 mx(k*l) 矩阵从右侧击中 A .
【讨论】: