4

我有值介于1和之间的向量N > 1。有些值可能会连续出现多次。现在我想要第二行来计算连续条目并删除所有连续出现的条目,例如:

A = [1 2 1 1 3 2 4 4 1 1 1 2]'

会导致:

B = [1 1;
     2 1;
     1 2;
     3 1;
     2 1;
     4 2;
     1 3;
     2 1]

(你看,第二列包含连续条目的数量!我最近在 MATLAB 中遇到过accumarray(),但我找不到任何解决方案,因为它总是考虑整个向量而不仅仅是连续条目。

任何的想法?

4

2 回答 2

5

这可能不是最易读或最优雅的方式,但如果你有大向量并且速度是一个问题,这种向量化可能会有所帮助......

A = [1 2 1 1 3 2 4 4 1 1 1 2];

首先,我要用前导零和尾随零填充 A 以捕获第一个和最后一个转换

>>  A = [0, A, 0];

可以找到相邻值之间的差异不等于 0 的过渡位置:

>> locations = find(diff(A)~=0);

但是因为我们用零填充了 A 的开头,所以第一个转换是无意义的,所以我们只取 2:end 的位置。其中A中的值是每个段的值:

>> first_column = A(locations(2:end))

ans =

     1     2     1     3     2     4     1     2

这是第一个列 - 现在查找每个数字的计数。这可以从位置的不同中看出。这是在两端填充 A 变得重要的地方:

>> second_column = diff(locations)

ans =

 1     1     2     1     1     2     3     1

最后结合:

B = [first_column', second_column']

B =

 1     1
 2     1
 1     2
 3     1
 2     1
 4     2
 1     3
 2     1

这一切都可以组合成一个可读性较差的行:

>> A = [1 2 1 1 3 2 4 4 1 1 1 2]';
>> B = [A(find(diff([A; 0]) ~= 0)), diff(find(diff([0; A; 0])))]

B =

 1     1
 2     1
 1     2
 3     1
 2     1
 4     2
 1     3
 2     1
于 2012-01-20T13:49:27.833 回答
2

我没有看到循环数据集的另一种方法,但它相当简单。也许这不是最优雅的解决方案,但据我所知,它工作正常。

function B = accum_data_set(A)
    prev = A(1);
    count = 1;
    B = [];
    for i=2:length(A)
        if (prev == A(i))
            count = count + 1;
        else
            B = [B;prev count];
            count = 1;
        end
        prev = A(i);
    end
    B = [B;prev count];

输出:

>> A = [1 2 1 1 3 2 4 4 1 1 1 2]';
>> B = accum_data_set(A)

B =

     1     1
     2     1
     1     2
     3     1
     2     1
     4     2
     1     3
     2     1
于 2012-01-20T13:39:56.710 回答