【问题标题】:What mathematical function does reshape perform?reshape 执行什么数学函数?
【发布时间】:2019-04-08 20:00:07
【问题描述】:

在 Python 和 MATLAB 中,您都可以使用名为 reshape() 的函数来更改矩阵的维度。

这是线性代数中的什么运算,是基的变化,还是更简单的矩阵乘法,或者两者都不是?

【问题讨论】:

  • 您查看过reshape 文档 (MATLAB) 中的示例吗?

标签: python matlab matrix reshape


【解决方案1】:

这个函数与线性代数无关,它是一个简单的索引技巧。考虑以下情况(我将使用 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),因为它的外观发生了变化。

【讨论】:

  • 任何参考?你所展示的只是简单的转置。我不确定在更复杂的重塑中是否会相同。
  • @Karls 只是在 MATLAB 中处理这个,A 的转置将是 [1 4; 2 5; 3 6],这是与转置矩阵不同的矩阵。转置改变了元素的顺序,因此它比简单的重塑更昂贵
  • 好吧,对,不等于转置。我仍然认为它可能比标题更复杂。你有什么参考资料可以支持你的解释吗?
  • @Karls:参考是 reshape 的文档,Adriaan 链接了该文档,以及 this other documentation page
  • 您可以创建一个非常大的数组,并计算进行整形需要多长时间以及进行转置需要多长时间。你会看到reshape 是微不足道的,没有数据被复制,并且转置需要相当长的时间,它确实复制了数据。
【解决方案2】:

根据 python 文档 1,2,它只是分解数组(因此使 t 成为线性一维向量。然后,使用索引,它返回到新数组定义的大小。例如:

start_array = 
[1,2,3,4;
5,6,7,8;
9,10,11,12]

i_a = [1,2,3,4,5,6,7,8,9,10,11,12] %implicit, not visible for user

result_array = 
[i_a(1), i_a(6), i_a(11); 
i_a(5), i_a(10), i_a(4); 
i_a(9), i_a(3), i_a(8); 
i_a(2), i_a(7), i_a(12)]

【讨论】:

  • 您现在认为您的元素是行主要的;它们不是,而是以列优先顺序存储(至少在 MATLAB 中,您正在使用哪种语法)。
  • 行或列的顺序在这里无关紧要,它只显示概念。我基于官方 Python SciPy 文档,在 MATLAB 中可以通过其他方式完成。
  • 在底层,numpy 数组总是像 MATLAB,一维。它只是改变了将 2D(在这种情况下)索引转换为该 1D 数组的方式,以及它如何显示它们。
  • 引用自文档You can think of reshaping as first raveling the array [...] then inserting [...] using the same kind of index。因此,如果它们是原生线性存储的,那听起来很琐碎。
【解决方案3】:

您可以重塑的最简单的矩阵是 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 .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2022-01-17
    • 1970-01-01
    相关资源
    最近更新 更多