【问题标题】:Creating a matrix from a vector with a specific indexing without a loop从具有特定索引的向量创建矩阵而无需循环
【发布时间】:2018-07-19 16:55:27
【问题描述】:

我有一个向量和一个这样的矩阵:

v = [0.3 -3 3 -2 7 6]
INDEX = [1 3; 3 5; 4 6]

INDEX 是一个矩阵,表示vRESULT 行必须具有的第一个和最后一个元素。我确保INDEX 中的每个间隔,即 1 to 33 to 54 to 6 具有相同的长度,因此 RESULT 矩阵中的每一行都具有相同的长度。

我想得到一个这样的矩阵:

RESULT = [0.3 -3  3; 
            3 -2  7; 
           -2  7  6] 

如何在没有for 循环的情况下执行此操作?

【问题讨论】:

  • INDEX(即3 x 2)到RESULT(即3 x 3)究竟是如何得到的?
  • @excaza 他的意思是从1 3(即1,2,3)
  • 是的,@MehrdadZandigohar 是对的,如果有误导,我很抱歉
  • 我确保间隔具有相同的长度,所以每一行都有相同的长度

标签: matlab matrix vector indexing vectorization


【解决方案1】:

确定INDEX 每一行的最后一个值和第一个值之间的差异。使用此差异生成所需的索引,然后使用这些索引提取所需的值。

idx = [INDEX(:,1) INDEX(:,1)+[1:INDEX(1,end)-INDEX(1,1)]];  %Generating the indices
%for finding indices in <= R2016a, use this:
%idx = [INDEX(:,1) bsxfun(@plus, INDEX(:,1), [1:INDEX(1,end)-INDEX(1,1)])];
RESULT = v(idx); 

【讨论】:

  • 这很好,谢谢! (不幸的是,它仍然比 for 循环花费更多时间)。
  • @ViniciusM 我不希望索引比任何东西都慢。你是如何计时的,数据大小是多少?还要在原始帖子中包含带有该循环的代码
  • v 有 2400000 个元素,INDEX 有 114 行,结果最终是 114 x 16832。我正在用一个简单的 tic toc 计时。
  • @ViniciusM 用timeit 计时。 tic toc 用于大致了解时间,
  • @ViniciusM 你能分享你的for循环吗?
【解决方案2】:

答案如下:

RESULT=v(cell2mat(arrayfun(@colon, INDEX(:,1), INDEX(:,2), 'Uniform', false)))

它的工作原理如下:

您应该首先创建一个包含INDEX 矩阵的所有索引的矩阵。

下面的代码创建了一个包含所有索引的单元格(而不仅仅是区间的开头和结尾):

cell_index=arrayfun(@colon, INDEX(:,1), INDEX(:,2), 'Uniform', false)

然后你应该通过cell2mat函数将它从单元格转换为矩阵:

mat_index=cell2mat(cell_index)

最后,将索引替换为v 向量:

RESULT=v(mat_index)

【讨论】:

  • OP 想要没有循环。 arrayfun 本身就是一个循环
  • 我的意思是,这是一个很好的答案,谢谢。但是,这比执行 for 循环要花费更多时间。
【解决方案3】:

在这种情况下最简单的解决方案是

RESULT=v([INDEX(:,1) INDEX(:,1)+1 INDEX(:,2)])

如果您的索引数组中可能有跨度覆盖精确的中间索引:

RESULT=v([INDEX(:,1) (INDEX(:,1)+INDEX(:,2))/2 INDEX(:,2)])

为了提供足够有效和通用的解决方案,您应该提供索引矩阵可以具有的约束。

【讨论】:

    猜你喜欢
    • 2023-01-21
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多