【问题标题】:How to Combine groups of duplicate and repeating values and preserving order? Matlab如何组合重复值和重复值组并保留顺序? MATLAB
【发布时间】:2013-09-11 01:48:47
【问题描述】:

我在组合我的 Matlab“数据”变量的重复元素时遇到问题。我可以使用 unique 和 sort 轻松组合值。

[sorted,idx] = sort(data);
[~,ij] = unique(sorted,'first');
Indx = (sort(idx(ij)));

但是,通过这样做,我合并了所有重复的值。我真正想做的是只组合重复元素的组。举个例子:

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

合并重复的元素组:

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

我需要在仍然保持顺序的情况下组合重复元素组。返回索引也很有帮助,因为我需要根据组合索引对另一个变量中的数据进行平均。

例如:

data  = [1;1;1;2;2;2;3;3;3;4;4;4;4;4;3;3;2;2;2;2;1;1;1;1;4;4;4;4;]
data2 = [7;2;4;5;3;4;6;8;5;3;5;7;4;2;4;6;8;4;3;6;7;8;4;2;9;3;2;0;]

dataCombined = [1;     2;  3;    4;   3;  2;     1;     4;   ]
data2average = [4.33;  4;  6.33  4.2  5;  5.25;  5.25;  3.5; ]

谁能给点建议?


解决方案:

谢谢大家的回答。 MZimmerman6 的解决方案对我来说效果很好。我想展示我做了什么来平均“data2”数组中的值。

data = [1;1;1;2;2;2;3;3;3;4;4;4;4;4;3;3;2;2;2;2;1;1;1;1;4;4;4;4;];
data2 = [7;2;4;5;3;4;6;8;5;3;5;7;4;2;4;6;8;4;3;6;7;8;4;2;9;3;2;0;];
change = diff(data)~=0;
indices = [1,find(change)'+1];
compressed = data(indices)';


numberOfRepeatingGroups = size(indices);


for i=1:numberOfRepeatingGroups(1,2)


  if(i == 1)   

      dataToAverage = data2(indices(1,1):(indices(1,2)-1));

  elseif (i == numberOfRepeatingGroups(1,2))

       dataToAverage = data2(indices(1,i):end);

  else

       dataToAverage = data2(indices(1,i):(indices(1,(i+1))-1));

  end

       data2Averaged(1,i) = mean(dataToAverage(:));

end   


data2Averaged =

4.3333    4.0000    6.3333    4.2000    5.0000    5.2500    5.2500    3.5000

【问题讨论】:

  • 只是一个简单的注释,而不是执行numberOfRepeatingGroups(1,2),只需执行size(indices,2),这将获得数组中的列数。或者由于indices 数组是一维的,您可以简单地使用length(indices)。它使您的代码更具可读性。

标签: matlab duplicates duplicate-removal


【解决方案1】:

您可以使用导数来查找数据数组中的波动,这表明分组发生了变化。导数不为 0 的任何地方都会发生变化,无论是正的还是负的。找到这些变化发生的地方,然后抓取相应的索引。如下所示。

data = [1;1;1;2;2;2;3;3;3;4;4;4;4;4;3;3;2;2;2;2;1;1;1;1;4;4;4;4;];
change = diff(data)~=0;
indices = [1,find(change)'+1];
compressed = data(indices)';

结果是

compressed =
     1     2     3     4     3     2     1     4

当然,您也可以根据需要使用indices 变量。

注意 在第三行,我们添加索引 1,因为从技术上讲,数组的开头是一个变化,然后我们在 find 命令中添加 1,因为我们在导数上使用 find,所以返回的 change 数组将比 1 短原本的。

【讨论】:

  • 这正是我所需要的。我真的不能感谢你!使用导数非常聪明,如果没有你的帮助,我想我永远也想不通!
  • 没问题。这就是我们在这里的目的。
【解决方案2】:

我永远不会停止从 File Exchange: rude() 推荐这个运行长度编码/解码实用程序。

% Run-length encode preserving order
[len,val] = rude(data);
len =
     3     3     3     5     2     4     4     4
val =
     1     2     3     4     3     2     1     4

现在,要计算平均值,首先用rude() 重新标记每个子序列,然后使用accumarray()

% Decode and re-label each subsequence
subs = rude(len,1:numel(len))';

% Take average on each re-labelled subsequence
accumarray(subs,data2,[],@mean)
ans =
    4.3333
    4.0000
    6.3333
    4.2000
    5.0000
    5.2500
    5.2500
    3.5000

【讨论】:

  • 这也是一个很好的解决方案,但我几乎总是会推荐一些初学者使用他们“自己”编写的代码的东西。当然,他们不是在编写 diff 函数,但可以理解它在幕后所做的事情。无论如何,我仍然给你 +1 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2014-09-04
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多