I'd like to assign a cumulative numerical value for sequential runs in a binary vector. What I have is
我想为二进制向量中的顺序运行分配累积数值。我拥有的是什么
x = [0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 0 0],
and what I would like is
我想要的是什么
y = [1 2 3 1 2 1 1 2 3 1 1 1 2 3 4 5 6].
The solution using sum/cumsum/unique/find range of functions alludes me. Any help would be greatly appreciated.
使用sum / cumsum / unique / find范围的函数的解决方案暗示了我。任何帮助将不胜感激。
3 个解决方案
#1
6
Here's a way:
这是一种方式:
a = arrayfun(@(x)(1:x), diff(find([1,diff(x),1])), 'uni', 0);
[a{:}]
The idea is to generate a list of the 'run lengths', i.e. [3,2,1,3,1,1,6]
in your case, then just concatenate a bunch of vectors that count to each value in that list, i.e. cat(2, 1:3, 1:2, 1:1, 1:3...
. I use arrayfun
as a shortcut for reapplying the :
operator and then use the comma separated list that {:}
returns as a shortcut for the concatenation.
我的想法是生成一个'运行长度'列表,即你的情况下的[3,2,1,3,1,1,6],然后只连接一组计数到该列表中每个值的向量,即cat(2,1:3,1:2,1:1,1:3 ....我使用arrayfun作为重新应用:运算符的快捷方式,然后使用逗号分隔列表{:}作为快捷方式返回为了连接。
#2
6
(Not a one-liner, alas ...):
(不是单行,唉...):
F = find(diff(x))+1;
y = ones(size(x));
y(F) = y(F)-diff([1,F]);
y = cumsum(y);
First, find all positions in x
where there is a change; then build a vector of 1 where you substract the length of each continuous segment. At the end, take the cumsum of it.
首先,找到x中所有位置发生变化的位置;然后构建一个1的向量,您可以减去每个连续段的长度。最后,拿出它的痕迹。
#3
1
Create a sparse
matrix such that each run is on a different column, and then do the cumulative sum:
创建一个稀疏矩阵,使每次运行在不同的列上,然后执行累积和:
t = sparse(1:numel(x), cumsum([1 diff(x)~=0]), 1);
y = nonzeros(cumsum(t).*t).';
Use accumarray
with a custom function to generate each increasing pattern in a different cell, and then concatenate all cells:
使用带有自定义函数的accumarray在不同的单元格中生成每个增加的模式,然后连接所有单元格:
y = accumarray(cumsum([1 diff(x)~=0]).', 1, [], @(x) {1:numel(x).'});
y = [y{:}];
#1
6
Here's a way:
这是一种方式:
a = arrayfun(@(x)(1:x), diff(find([1,diff(x),1])), 'uni', 0);
[a{:}]
The idea is to generate a list of the 'run lengths', i.e. [3,2,1,3,1,1,6]
in your case, then just concatenate a bunch of vectors that count to each value in that list, i.e. cat(2, 1:3, 1:2, 1:1, 1:3...
. I use arrayfun
as a shortcut for reapplying the :
operator and then use the comma separated list that {:}
returns as a shortcut for the concatenation.
我的想法是生成一个'运行长度'列表,即你的情况下的[3,2,1,3,1,1,6],然后只连接一组计数到该列表中每个值的向量,即cat(2,1:3,1:2,1:1,1:3 ....我使用arrayfun作为重新应用:运算符的快捷方式,然后使用逗号分隔列表{:}作为快捷方式返回为了连接。
#2
6
(Not a one-liner, alas ...):
(不是单行,唉...):
F = find(diff(x))+1;
y = ones(size(x));
y(F) = y(F)-diff([1,F]);
y = cumsum(y);
First, find all positions in x
where there is a change; then build a vector of 1 where you substract the length of each continuous segment. At the end, take the cumsum of it.
首先,找到x中所有位置发生变化的位置;然后构建一个1的向量,您可以减去每个连续段的长度。最后,拿出它的痕迹。
#3
1
Create a sparse
matrix such that each run is on a different column, and then do the cumulative sum:
创建一个稀疏矩阵,使每次运行在不同的列上,然后执行累积和:
t = sparse(1:numel(x), cumsum([1 diff(x)~=0]), 1);
y = nonzeros(cumsum(t).*t).';
Use accumarray
with a custom function to generate each increasing pattern in a different cell, and then concatenate all cells:
使用带有自定义函数的accumarray在不同的单元格中生成每个增加的模式,然后连接所有单元格:
y = accumarray(cumsum([1 diff(x)~=0]).', 1, [], @(x) {1:numel(x).'});
y = [y{:}];