【问题标题】:delete certain columns of matrix when number of zero elements exceeds threshold avoiding loop当零元素的数量超过阈值时删除矩阵的某些列避免循环
【发布时间】:2014-10-15 05:57:16
【问题描述】:

我有一个很大的(107 x n) 矩阵X。在这些n 列中,每个three 列都属于彼此。所以,矩阵Xfirst three 列构建一个块,然后列4,5,6 等等。

在每个块中,first 列的first 100 行元素很重要X(1:100,1:3:end)。只要在第一列中zerosNaNs 的数量大于或等于20,它就应该删除整个块。

有没有办法在没有循环的情况下做到这一点?

感谢您的建议!

【问题讨论】:

    标签: matlab vectorization


    【解决方案1】:

    假设输入的列数是3 的倍数,这里可能有两种方法。

    方法#1

    %// parameters
    rl = 100; %// row limit 
    cl = 20; %// count limit
    
    X1 = X(1:rl,1:3:end) %// Important elements from input
    match_mat = isnan(X1) | X1==0 %// binary array of matches
    match_blk_id = find(sum(match_mat)>=cl) %// blocks that satisfy requirements
    match_colstart = (match_blk_id-1).*3+1 %// start column indices that satisfy
    all_col_ind = bsxfun(@plus,match_colstart,[0:2]') %//'columns indices to be removed
    X(:,all_col_ind)=[] %// final output after removing to be removed columns
    

    或者,如果您更喜欢“紧凑”代码 -

    X1 = X(1:rl,1:3:end);
    X(:,bsxfun(@plus,(find(sum(isnan(X1) | X1==0)>=cl)-1).*3+1,[0:2]'))=[];
    

    方法 #2

    X1 = X(1:rl,1:3:end)
    match_mat = isnan(X1) | X1==0 %// binary array of matches
    X(:,repmat(sum(match_mat)>=cl,[3 1]))=[] %// Find matching blocks, replicate to
                                %// next two columns and remove them from X
    

    注意:如果 X 不是 3 的倍数,请在使用代码之前使用它 - X = [X zeros(size(X,1) ,3 - mod(size(X,2),3))]

    【讨论】:

    • 如果 X 不是 3 的倍数,则用零填充 - X = [X zeros(size(X,1) ,3 - mod(size(X,2),3))],然后使用此解决方案。
    • 非常感谢迪瓦卡!乍一看,它似乎解决了这个问题,至少它正确地截断了 X 矩阵。现在由我来理解你是如何解决它的:-) p.s. n 是三的倍数
    • @rookieMI 使用少量输入并获取每个步骤的输出并进行分析。小cmets也必须帮忙! :)
    • @rookieMI 也检查方法 #2!
    • 更优雅:-)
    猜你喜欢
    • 2020-12-24
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多