代码之家  ›  专栏  ›  技术社区  ›  Axel

通过保留具有最大值的键值对,删除具有公差的重复键值对

  •  1
  • Axel  · 技术社区  · 7 年前

    我正在尝试使用以下规则从一组键和值中删除具有公差的重复项:

    假设如下:

    keys = [1 2 3 3.1 3.15 4 5];
    vals = [0.8 1 1.1 1.3 1.2 1 1.1];
    

    绘制如下: Plotted key value pair

    现在我要删除那些键非常接近的对,如图中红色圆圈所示。我想保留的键值对是值最大的那个(在示例中是中间的那个 [3.1; 1.3] ,因此结果集将是:

    keys = [1 2 3.1 4 5];
    vals = [0.8 1 1.3 1 1.1];
    

    我试着用Matlab的 diff 函数通过执行

    vals_new = keys(~(diff(keys) < 0.5));
    keys_new = vals(~(diff(keys) < 0.5));
    [M,I] = max(vals(diff(keys) < 0.5));
    

    这将使vals_new和keys_new成为一个新的集,它只包含重复对中的最后一个,但也缺少最后一个值:

    keys_new = [1 2 3.15 4]
    vals_new = [0.8 1 1.2 1]
    

    最后一行返回重复对的最大值的索引。 I=2 ,但不幸的是不包括三个重复对中的最后一个 [3.15; 1.2] 所以这更像是一个巧合。

    我觉得应该有一个更聪明的方法来做这件事,但我真的没办法。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Hunter Jiang    7 年前

    以下是我的解决方案:

    第一步。 找到当前密钥和VAL中的所有非最大值点(其前面或后面有一个较大的邻居),然后构建一个名为 Nind 是的。

    第二步。 创建另一个名为 Cind ,其中包含有近邻且需要在当前键和值中考虑的每个点。

    第三步。 横断 尼德 煤渣 ,并删除 Keys Vals 是的。

    第四步。 如果两个集合的交集为空,则转到 步骤5 是的。在其他情况下,转到 步骤1 是的。

    第五步。 结束了~

    注意while循环处理的是一些具有多个最大值点的丑陋输入,例如:

    enter image description here

    我的代码:

    %% Input
    clc; clear;
    keys = [1 2 3 3.1 3.15 4 5];
    vals = [0.8 1 1.1 1.3 1.2 1 1.1];
    
    
    %% Dealing
    ind=-1;
    while(~isempty(ind))
      %find the non-max point
      Max=([diff(vals) 0]<0 & [0 -diff(vals)]<0); 
      Nind=1:length(vals);
      Nind(Max)=[];
    
      %determine the range of points
      Cind=[0 diff(keys)<0.5];
      Cind(find(Cind)-1)=1;
      vec=1:length(Cind);
      Cind=Cind.*vec;
      Cind(Cind == 0)=[];
    
      %check through & back
      ind=intersect(Cind,Nind);
      keys(ind)=[];
      vals(ind)=[];
    end
    
    %% Output
    [keys;vals]
    

    代码的输出是:

    ans =
    
        1.0000    2.0000    3.1000    4.0000    5.0000
        0.8000    1.0000    1.3000    1.0000    1.1000