【问题标题】:return the index of the last K non-zero element of each row of a matrix返回矩阵每行最后 K 个非零元素的索引
【发布时间】:2016-09-07 20:22:20
【问题描述】:

有没有一种向量化的方式来返回矩阵每一行最后K个非零元素的索引?

例如,我的矩阵只包含0和1,每行的最后一列总是1。那么我想找到最后K的索引,其中K>1,每行的非零元素。如果一行只有 M(小于 K)个非零元素,那么该行的索引就是最后 M 个非零元素的索引。例如

A = [0 1 0 1;
     1 1 0 1;
     1 1 1 1;
     0 0 0 1]

而我的 K = 2,那么我期望返回一个这样的矩阵

B = [0 1 0 1;
     0 1 0 1;
     0 0 1 1;
     0 0 0 1]

B原本是一个与A形状相同的零矩阵,然后它复制A的每一行,其中对应的列从@行的最后K个非零元素的索引开始987654326@(如果A的一行中只有MA那一行的最后M个非零元素的索引开始)

【问题讨论】:

  • 只是为了确定,对于A 中的任何行r,您想获得find(A(r,1:end-1)>0,1,'last'),但不循环r
  • 几乎正确,我想找到最后K个非零元素,其中K是给定参数
  • 所以你找A(r,find(A(r,1:end-1)~=0,K,'last'))B矩阵上的整个部分真的不清楚...
  • 我同意你的看法。但最终,我想生成一个矩阵 B,这样我就可以将矩阵 B 的每一行用作某个索引集。

标签: matlab vectorization


【解决方案1】:

知道元素只有01,您可以在翻转矩阵A 上使用cumsum 制作掩码,并丢弃累积和大于k 的值:

A = [0 1 0 1;1 1 0 1;1 1 1 1;0 0 0 1]
k = 2;

C = fliplr(cumsum(fliplr(A), 2));   % take the cumulative sum backwards across rows
M = (C <= k);                       % cumsum <= k includes 0 elements too, so...
B = A .* M                          % multiply original matrix by mask

如 cmets 中所述(感谢 @KQS!),如果您使用的是最新版本的 MATLAB,cumsum 有一个 direction 可选参数,因此可以缩短生成 C 的行到:

C = cumsum(A, 2, 'reverse');

结果: 一个=

   0   1   0   1
   1   1   0   1
   1   1   1   1
   0   0   0   1

B =

   0   1   0   1
   0   1   0   1
   0   0   1   1
   0   0   0   1

【讨论】:

  • 在较新版本的 MATLAB 中,cumsum 采用可选的“方向”参数,因此您可以这样做:C = cumsum(A,2,'reverse');
  • @KQS 哦,这让它变得更好。 :D 我在 Octave 上执行此操作,它没有该选项,但我会将其添加到答案中。谢谢!
【解决方案2】:

知道find 函数可以获取最后k 个元素的索引,我们可以使用bsxfun 将find 应用于矩阵的行以查找每行中的哪个元素满足条件。 find 再次用于提取结果矩阵的非零元素的行和列,从而减少数据的大小和操作的复杂性。然后将结果保存到稀疏矩阵然后转换为完整矩阵:

A = [0 1 0 1;
     1 1 0 1;
     1 1 1 1;
     0 0 0 1]
k = 2;
[row , col]= size(A);
last_nz = bsxfun(@(a,b)find(a,b,'last'),A',(repmat(k, 1, row))); %get indices of last two nonzero elements for each row
[~,rr,cc]=find(last_nz); %get columns and rows of correspondong element for whole matrix
B = full(sparse(rr,cc,1));

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 2017-05-11
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    • 2014-04-30
    相关资源
    最近更新 更多