我有一个由列向量组成的矩阵,其值取 0 或 1。我希望实现的是某种形式的自动化过程,该过程创建一个简洁的结构来显示结果。也就是说,该过程将创建结果向量 v1,v2,v3,v4,v5,它们对应于每个列变量的每个序列中连续 1 的数量。
例如 d=
0 1 1 1 1
1 1 0 0 0
1 1 1 0 1
0 0 0 0 0
1 1 0 1 1
我们得到 v1=[2,1] v2=[3,1] v3=[1,1] v4=[1,1] v5=[1,1,1]
我有一个由列向量组成的矩阵,其值取 0 或 1。我希望实现的是某种形式的自动化过程,该过程创建一个简洁的结构来显示结果。也就是说,该过程将创建结果向量 v1,v2,v3,v4,v5,它们对应于每个列变量的每个序列中连续 1 的数量。
例如 d=
0 1 1 1 1
1 1 0 0 0
1 1 1 0 1
0 0 0 0 0
1 1 0 1 1
我们得到 v1=[2,1] v2=[3,1] v3=[1,1] v4=[1,1] v5=[1,1,1]
这没有循环。
代码应该是不言自明的,否则问我。结果变量是一个元胞数组,因为结果对于 的每一列都有不同的大小d
。
nrows = size(d,1);
d_neg_cell = num2cell(~d,[nrows 1]);
zeros_d = cellfun(@find, d_neg_cell, 'UniformOutput', 0);
find_runs = @(v) nonzeros( diff([0; v; nrows+1])-1 ).';
sol = cellfun(find_runs, zeros_d, 'UniformOutput', 0);
对于您的d
矩阵,这给出了:
>> sol{:}
ans =
2 1
ans =
3 1
ans =
1 1
ans =
1 1
ans =
1 1 1
遍历列,在开头和结尾添加零以进行正确的边缘检测,进行差异并使用正值和负值来查找上升沿和下降沿的位置。这些位置的差异为您提供了序列的长度。这是代码
v = {};
for e = d,
f = diff([0 e' 0]);
v{end+1} = find(f<0) - find(f>0);
end
返回
>> v{:}
ans =
2 1
ans =
3 1
ans =
1 1
ans =
1 1
ans =
1 1 1
编辑回复 OP 的评论:
如果列包含NaN
并且您想忽略它们,请更改使用 diff 的行并传递不带NaN
值的数组:
v = {};
for e = d,
f = diff([0 e(~isnan(e))' 0]);
v{end+1} = find(f<0) - find(f>0);
end