2015-01-13 15 views
5

我想为二进制向量中的顺序运行分配累计数值。我有什么是为数字运行分配顺序计数

x = [0 0 0 1 1 0 1 1 1 0 1 0 0 0 0 0 0], 

什么,我想是

y = [1 2 3 1 2 1 1 2 3 1 1 1 2 3 4 5 6]. 

使用金额/ cumsum /独特的解决方案/查找功能的范围暗示我。任何帮助将不胜感激。

回答

6

这里有一个办法:

a = arrayfun(@(x)(1:x), diff(find([1,diff(x),1])), 'uni', 0); 
[a{:}] 

的想法是产生“跑长”名单,即[3,2,1,3,1,1,6]你的情况,那么就串联了一堆的载体,在该列表中算到每个值,即cat(2, 1:3, 1:2, 1:1, 1:3...。我使用arrayfun作为重新应用:运算符的快捷方式,然后使用{:}返回的逗号分隔列表作为并置的快捷方式。

+0

美丽的一行,尤其是对'的伎俩:' – Bentoy13

+0

好点在应用''@(x)的1:x''对游程恩编码! – Nras

+0

哇。大!你的一件衬衫非常酷(而且很复杂),有时候会让我头痛!不错的工作。 –

6

(不是一个衬垫,唉...):

F = find(diff(x))+1; 
y = ones(size(x)); 
y(F) = y(F)-diff([1,F]); 
y = cumsum(y); 

首先,找到x所有的位置,那里是一个改变;然后建立一个1的矢量,减去每个连续片段的长度。最后,拿它的cumsum。

+0

这是一个聪明的做法! – Dan

+0

在阅读这个问题时,我的脑海里总是怀着“find”,“diff”,特别是“cumsum”的嫌疑。这看起来非常类似于我的(但不存在的)方法。 – Nras

+0

这是我最初想到的解决方案类型 - 但无法完成工作。非常感谢@ Bentoy13。 –

1

创建sparse矩阵,使得每个运行是在不同的列中,然后执行累计总和:

t = sparse(1:numel(x), cumsum([1 diff(x)~=0]), 1); 
y = nonzeros(cumsum(t).*t).'; 

使用accumarray与自定义函数来产生在不同的小区中的每个增加图案,然后串联的所有单元格:

y = accumarray(cumsum([1 diff(x)~=0]).', 1, [], @(x) {1:numel(x).'}); 
y = [y{:}]; 
+0

我从未考虑过的替代解决方案。 –