Dav*_*d K 3 arrays indexing matlab vector
我需要看起来像这样的数据向量:
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];
我想删除所有重复的相邻值A并将相应的值相加B,结果为
A = [1 2 3  4 5 6  5 4  3];
B = [1 5 15 4 6 10 1 12 19];
我可以unique像在这个答案中描述的那样使用,但是这将组合所有重复的值,重复的值,无论顺序如何.我也可以使用diff,如本问题所述,但我不知道如何记录将合并的索引.
我总是可以迭代矢量,但这似乎是不必要的乏味,我觉得应该有一个更优雅的解决方案.有没有办法在几行中实现这一目标?
您可以使用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
我承认这不是几行,因为大多数是设置,但核心答案可以在第二行,第三行和最后一行代码中看到.注意accumarray输入需要为列向量的微妙之处.为了强制输入它们是列向量,我用它将向量(:)展开到列中而不管它们的形状如何,尤其是第一行代码.然后我将结果转置到最后,因为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
cumsum对ID数组执行转换此diff数组,以便每个连续的组为您提供唯一的ID.我们还可以使用ind索引A来查找每组的唯一值,即第三行.最后一行对每个组进行求和.请注意,当我展开数据时,第三行被转换为行向量,因此它是一个以列开头的向量.
我们得到了所需的输出:
>> Aout
Aout =
     1     2     3     4     5     6     5     4     3
>> Bout
Bout =
     1     5    15     4     6    10     1    12    19