【问题标题】:Vectorized Reshaping of Columns in an Array数组中列的矢量化重塑
【发布时间】:2012-11-27 02:44:49
【问题描述】:

我有一个数组 A,并且想将每列的最后四个元素重新整形为一个 2x2 矩阵。我希望将结果存储在单元格数组 B 中。

例如,给定:

A = [1:6; 3:8; 5:10]';

我希望 B 包含三个 2x2 数组,这样:

B{1} = [3, 5; 4, 6];
B{2} = [5, 7; 6, 8];
B{3} = [7, 9; 8, 10];

我显然可以在 for 循环中使用 reshape(A(end-3:end, ii), 2, 2) 之类的东西并在 ii 上循环。任何人都可以提出一种矢量化方法,也许使用类似于cellfun 的方法,可以将操作重复应用于数组的列?

【问题讨论】:

  • 我不确定您是否需要进行任何重塑才能达到您想要的结果。为什么不使用for i = 1:3:B{i} = A((2*i-1):2*i, 2:3);?您是否有需要“矢量化”的性能问题?
  • 啊,我知道我选择了一个令人困惑的例子。我取的是一列的最后四个元素,而不是 A 的平方子集。此外,这个简单的示例不需要额外的性能 - 我打算将其扩展为从大量 ode45 数据创建 18x18 数组。从技术上讲,它也不需要它;我主要是对未来的参考感到好奇。

标签: arrays matlab octave vectorization


【解决方案1】:

我这样做的方法是查看所需的索引,然后找出生成它们的方法,通常使用某种形式的 repmat。例如,如果您想要每列中的最后 4 个项目,A 的(绝对)索引将是 3、4、5、6,然后将行数添加到移动到下一列得到 9 ,10,11,12 等等。因此,问题就变成了根据您的行数、列数以及每列所需的元素数(我将其称为 n,在您的情况下为 n = 4)生成该矩阵。

octave:1>  A = [1:6; 3:8; 5:10]'
A =

    1    3    5
    2    4    6
    3    5    7
    4    6    8
    5    7    9
    6    8   10

octave:2>  dim=size(A)
dim =

   6   3

octave:3> n=4
n =  4
octave:4> x=repmat((dim(1)-n+1):dim(1),[dim(2),1])'
x =

   3   3   3
   4   4   4
   5   5   5
   6   6   6

octave:5> y=repmat((0:(dim(2)-1)),[n,1])
y =

   0   1   2
   0   1   2
   0   1   2
   0   1   2

octave:6> ii=x+dim(1)*y
ii =

    3    9   15
    4   10   16
    5   11   17
    6   12   18

octave:7> A(ii)
ans =

    3    5    7
    4    6    8
    5    7    9
    6    8   10

octave:8> B=reshape(A(ii),sqrt(n),sqrt(n),dim(2))
B =

ans(:,:,1) =

   3   5
   4   6

ans(:,:,2) =

   5   7
   6   8

ans(:,:,3) =

    7    9
    8   10

根据您生成 x 和 y 的方式,您甚至可以取消乘法,但我将把它留给您。 :D

IMO 你也不需要一个单元格数组来存储它们,一个 3D 矩阵也可以工作,并且你以同样的方式索引它(但不要忘记在使用它之前squeeze它)。

我在this question.给出了类似的答案

【讨论】:

  • 谢谢墨菲。同意 3D 矩阵,它很好地简化了事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多