我的矢量值介于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()
,但我找不到任何解决方案,因为它始终关注整个向量而不仅仅是连续的条目。
有什么想法吗?
答案 0 :(得分:5)
这可能不是最可读或最优雅的方式,但如果你有大的向量和速度是一个问题,这个矢量化可能有帮助......
A = [1 2 1 1 3 2 4 4 1 1 1 2];
首先,我要用一个前导零和尾随零来填充A以捕获第一个和最后一个转换
>> A = [0, A, 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
这是第一个colomn - 现在可以找到每个数字的数量。这可以从位置的差异中找到。这就是两端填充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
答案 1 :(得分: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