【问题标题】:Transform a matrix to a stacked vector where all zeroes after the last non-zero value per row are removed将矩阵转换为堆叠向量,其中每行最后一个非零值之后的所有零都被删除
【发布时间】:2016-05-27 13:13:58
【问题描述】:

我有一个矩阵,其中包含一些我想擦除的零值。

a=[ 1 2 3 0 0; 1 0 1 3 2; 0 1 2 5 0]

>>a =

 1     2     3     0     0
 1     0     1     3     2
 0     1     2     5     0

但是,我只想删除每行最后一个非零值之后的那些。 这意味着我想从第一行保留1 2 3,从第二行保留1 0 1 3 2,从第三行保留0 1 2 5

然后我想将剩余的值存储在一个向量中。在示例的情况下,这将导致向量

b=[1 2 3 1 0 1 3 2 0 1 2 5]

我想出的唯一方法涉及我想避免的 for 循环:

b=[];
for ii=1:size(a,1)
    l=max(find(a(ii,:)));
    b=[b a(ii,1:l)];
end

有没有办法向量化这段代码?

【问题讨论】:

  • 我已经编辑了您的标题,使其更能描述您的特定问题。使您的帖子标题“我如何矢量化此代码”是没有意义的,它对任何人都没有帮助。如果其他人通过这种方式看到可能有同样问题的标题是什么,这肯定会有所帮助。我还编辑了您的帖子以进行一般语法修复。

标签: matlab matrix vector vectorization


【解决方案1】:

有很多可能的方法可以做到这一点,这是我的方法:

 arotate = a' %//rotate the matrix a by 90 degrees
 b=flipud(arotate)  %//flips the matrix up and down
 c= flipud(cumsum(b,1)) %//cumulative sum the matrix rows -and then flip it back.
 arotate(c==0)=[] 

 arotate =

  1     2     3     1     0     1     3     2     0     1     2     5

==========================编辑=====================

刚刚意识到 cumsum 可以有方向参数,所以应该这样做:

 arotate = a'
 b = cumsum(arotate,1,'reverse')
 arotate(b==0)=[] 

此方向参数在我的 2010b 版本上不可用,但如果您使用的是 2013a 或更高版本,则应该有。

【讨论】:

    【解决方案2】:

    这是一种使用bsxfun 的屏蔽能力的方法 -

    M = size(a,2); %// Save size parameter
    at = a.'; %// Transpose input array, to be used for masked extraction
    
    %// Index IDs of last non-zero for each row when looking from right side
    [~,idx] = max(fliplr(a~=0),[],2);
    
    %// Create a mask of elements that are to be picked up in a
    %// transposed version of the input array using BSXFUN's broadcasting
    out = at(bsxfun(@le,(1:M)',M+1-idx'))
    

    示例运行(展示掩码使用)-

    >> a
    a =
         1     2     3     0     0
         1     0     1     3     2
         0     1     2     5     0
    >> M = size(a,2);
    >> at = a.'; 
    >> [~,idx] = max(fliplr(a~=0),[],2);
    >> bsxfun(@le,(1:M)',M+1-idx') %// mask to be used on transposed version
    ans =
         1     1     1
         1     1     1
         1     1     1
         0     1     1
         0     1     0
    >> at(bsxfun(@le,(1:M)',M+1-idx')).'
    ans =
         1     2     3     1     0     1     3     2     0     1     2     5
    

    【讨论】:

    • Divakar,你现在可以停止使用%// :)。现在已经引入了基本的 MATLAB 突出显示,因此只需执行 % 即可正确渲染 cmets。如果您将转置作为最后一条语句,则无需执行%.'
    • @rayryeng 哇,是的,我有点注意到有什么不对劲了哈哈。迷人的!谢谢你让我知道:)
    • '.' 的混合是故意的吗?我看到每次您知道矩阵包含整数(即大小和索引)时都会这样做。
    • @StewieGriffin 很好发现,是的,这是我所有帖子中有意为之的,这基本上就是原因,因为我确信尺寸不会很复杂,而且还有一点代码高尔夫思维:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-24
    • 2017-03-17
    • 1970-01-01
    • 2016-03-06
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多