您可以使用diff
首先找到并非唯一的相邻位置,然后将其与cumsum
结合使用,以便您可以生成应该属于彼此的不同组。在差异结果中查找非零值的任何值都将找到那些非唯一但连续的值。当您将cumsum
应用于此结果时,您将生成一个ID数组,该数组从1到多个组不等,其中所有属于同一ID的值都属于同一个连续组。这应该作为一种理想的投入accumarray
,我们可以总结所有的值属于每个组:
Aval = A(:); % Unroll into a column to ensure shape compliance
ind = diff([Inf; Aval]) ~= 0; % Find all unique locations
IDs = cumsum(ind); % Create ID array
Aout = Aval(ind).'; % Determine all unique values per group
Bout = accumarray(IDs(:), B(:)).'; % Find their sum
我承认,这不是一个几行的大部分是设置,但核心答案见于第二,第三和最后一行代码。请注意0的细微处,其中输入要求为列向量。为了强制输入以使它们成为列向量,我使用(:)
将向量展开为列,而不管它们的形状如何,特别是对于第一行代码。然后,我最后转置结果,因为accumarray
将在此情况下输出列向量,并且转置将创建行向量,因为您希望将行向量作为所需结果。
为您的测试输入:
A = [1 2 3 3 4 5 6 6 5 4 4 3 3 3 3];
B = [1 5 9 6 4 6 8 2 1 5 7 8 3 2 6];
的diff
结果的输出提供:
>> ind.'
ind =
1 1 1 0 1 1 1 0 1 1 0 1 0 0 0
您可以准确地看到,这是零对应于非唯一连续的位置值。的ID阵列的输出一旦运行cumsum
给出:
>> IDs.'
IDs =
1 2 3 3 4 5 6 6 7 8 8 9 9 9 9
的ID阵列上执行cumsum
,使得每个连续组给你一个唯一的ID变换此diff
阵列。我们还可以使用ind
来索引A
以找到第三行的每个组的唯一值。最后一行总结每个组。请注意,第三行在展开数据时转换为行向量,以便它是一个以列开头的列向量。
我们得到所需的输出:
>> Aout
Aout =
1 2 3 4 5 6 5 4 3
>> Bout
Bout =
1 5 15 4 6 10 1 12 19
我有没有回答你的问题? – rayryeng
@rayryeng终于开始尝试了,它完全符合我的需求。 'cumsum'和'accumarray'这个技巧非常棒! –
嘿嘿,没问题。 'accumarray'和'cumsum'是我最喜欢的两个功能。我很高兴能和你分享这些信息! – rayryeng