【问题标题】:Create a vector that holds the index of all the columns which has non-zero values based on a condition根据条件创建一个包含所有具有非零值的列的索引的向量
【发布时间】:2014-10-02 04:54:51
【问题描述】:

我有一个填充了 0 和 1 的矩阵,我需要计算每行中 1 的数量。然后我需要知道哪一行的计数超过或等于特定限制(任何数字,例如 3)。在这些行中的 foreach 行之后,我需要创建一个向量,该向量保存该行中具有非零值的所有列的索引,并且在它上面和下面的所有行中,直到它到达一个计数为零的行。

示例: data 包含以下数据:

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

如果限制为 3,则输出应该是:

Row 3: col 4 5 2 5 7 
Row 6: col 2 2 3 4 3 

我已经读取了数据,并在下面的代码中数了数:

load('data');
mat(isnan(mat)) = 0;
[rows,cols,vals]  = find(mat~= 0);
unqRows=unique(rows);
countElinRows=histc(rows,unqRows);

根据评论员的要求进行编辑以澄清:

如果给定样本输入数组的第三行变成[0 1 0 0 0 0 1],那么我们必须只有这个输出 -

Row 6: col 2 2 3 4 3

【问题讨论】:

  • 是的,大卫,你说得对,抱歉打错了(已编辑)
  • 如果输入数组的第三行是[0 1 0 0 0 0 1],那么输出应该是什么?
  • 输出将是第 6 行,因为第 3 行没有 3 个
  • 所以输出只是第 6 行,它的值与问题中所述的值相同 - Row 6: col 2 2 3 4 3 ?
  • 是的,第 3 行中的示例 .. 它有三个 1,所以我们必须检查上面的行和上面的行,直到我们到达全为零的行(在这种情况下为第 1 行)并从第 2 行检查有任何列的列并将其放入我们的向量中.. 然后第 3 行然后第 4 行直到我们到达没有任何列的行。

标签: matlab matrix indexing


【解决方案1】:

假设 A 作为输入数组,看看这是否适合你 -

[sc1,sr1] = find(A') %//'# row and col indices for sorted rows
s_a1 = sum(A,2) %// sum input array along cols
bounds = find(s_a1==0) %// find bounds/gropus delimited by all zero rows
bounds = unique([1 ; bounds ; size(A,1)]) %// account for non all zero 
                                         %// starting and ending rows

cumsum1 = cumsum(s_a1==0) + double(sum(A(1,:))~=0) %// label groups

valid_groups = accumarray(cumsum1, s_a1, [], @max)>=3 %// valid groups

out = arrayfun(@(k1) sc1(sr1>=bounds(k1) & sr1<=bounds(k1+1)),...
    1:numel(bounds)-1,'un',0) %// find all indices within each group
out = out(valid_groups) %// select only the valid groups for the final output

celldisp(out) 的可视化输出。

【讨论】:

    【解决方案2】:

    为奇怪的代码道歉,但这是我能想到的最好的了

    [I1,~]=find(sum(mat,2)>=3)
    [I2,~]=find(sum(mat,2)==0)
    [~,CM]=find(diff(mod(sum(bsxfun(@le,I1,I2.')),2))~=0)
    [I,J]=arrayfun(@(t)find(mat(I2(CM(t)):I2(CM(t)+1),:)>0),1:length(CM),'UniformOutput',false)
    [~,w]=cellfun(@sort,I,'UniformOutput',false);
    J=arrayfun(@(t) J{t}(w{t}).',1:length(J),'UniformOutput',false)
    celldisp(J)
    

    这段代码确实有点过于复杂了。

    我已经在几个案例上测试过,似乎没问题,但很难确定。

    【讨论】:

    • 我并没有真正理解这个问题,所以我将添加一个完全不相关的评论。 celldisp 可能比查看结果的循环更好。 =)
    • 非常感谢大卫,它提供了非常好的输出但顺序不正确,我怎样才能以相同的顺序输出?
    • OK @User436823,最终更新。不过绝对是一段​​混乱的代码。
    • 感谢@David,但它不适用于其他示例
    • 如果你能给我一个失败的例子,我会看看,但由于你发布了一个模糊的问题,然后添加了更多的条件,我真的没有太多的动力。
    猜你喜欢
    • 1970-01-01
    • 2020-06-04
    • 1970-01-01
    • 2022-07-28
    • 2013-08-12
    • 2017-10-04
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多