在matlab中寻找向量中的删除元素

在matlab中寻找向量中的删除元素,matlab,vector,repeat,pruning,Matlab,Vector,Repeat,Pruning,我有一个过程,是迭代和随机修剪一个巨大的整数向量,我想找出哪些元素在每次迭代之间被删除。这个向量有很多重复,使用ismember()和setdiff()对我帮助不大 作为说明,如果X=[1,10,8,5,10,3,5,2]: step 0: X = 1,10,8,5,10,3,5,2 step 1: X = 1,10,8,10,3,5,2 (5 is removed) step 2: X = 1,10,8,3,2 (10 and 5 are removed) step 3: X = 10,8,3

我有一个过程,是迭代和随机修剪一个巨大的整数向量,我想找出哪些元素在每次迭代之间被删除。这个向量有很多重复,使用ismember()和setdiff()对我帮助不大

作为说明,如果X=[1,10,8,5,10,3,5,2]:

step 0: X = 1,10,8,5,10,3,5,2
step 1: X = 1,10,8,10,3,5,2 (5 is removed)
step 2: X = 1,10,8,3,2 (10 and 5 are removed)
step 3: X = 10,8,3,2 (1 is removed)
step 4: X = 2 (10, 8 and 3 are removed)
step 5: X = [] (2 is finally removed)
我的目标是找到在每个步骤中删除的元素(即5、10和5等等)。我可能会在两个步骤之间使用
hist(X,unique(X))
找到一个过于复杂的解决方案,但我认为matlab中存在一个更优雅(更便宜!)的解决方案

  • 这种方法是内存密集型的。它计算大小为
    N
    x
    M
    的中间矩阵,其中
    N
    x
    的元素数,
    M
    x
    的唯一元素数,使用。这可能可行或不可行,取决于您典型的
    N
    M

    X = [1,10,8,5,10,3,5,2];
    Y = [8,10,2,1]; % removed 10, 5, 5, 3. Order in Y is arbitrary
    u = unique(X(:).');
    removed = repelem(u, sum(X(:)==u,1)-sum(Y(:)==u,1));
    
    给予

    对于R2016b之前的Matlab版本,您需要的不是隐式扩展,而是:

    removed = repelem(u, sum(bsxfun(@eq,X(:),u),1)-sum(bsxfun(@eq,Y(:),u),1));
    
  • 如果
    X
    中的值始终为正整数,则可以使用更有效的方法计算每个元素出现的次数:

    X = [1,10,8,5,10,3,5,2];
    Y = [8,10,2,1]; % removed 10, 5, 5, 3. Order in Y is arbitrary
    removed = repelem(1:max(X), sparse(1,X,1) - sparse(1,Y,1));
    

  • 我提出了从输出中恢复输入的想法,方法是将两者相减,然后迭代不同的值,这些值就是被删除元素的索引

    % Input.
    X = [1, 10, 8, 5, 10, 3, 5, 2];
    
    % Remove indices for the given example.
    y = { [4], [4 6], [1], [1 2 3], [1] };
    
    % Simulate removing.
    for k = 1:numel(y)
    
      % Remove elements.
      temp = X;
      temp(y{k}) = [];
    
      % Determine number of removed elements.
      nRemoved = numel(X) - numel(temp);
    
      % Find removed elements by recovering input from output.
      recover = temp;
      removed = zeros(1, nRemoved);
      for l = 1:nRemoved
        tempdiff = X - [recover zeros(1, nRemoved - l + 1)];
        idx = find(tempdiff, 1);
        removed(l) = X(idx);
        recover = [recover(1:idx-1) X(idx) recover(idx:end)];
      end
    
      % Simple, stupid output.
      disp('Input:');
      disp(X);
      disp('');
      disp('Output:');
      disp(temp);
      disp('');
      disp('Removed elements:');
      disp(removed);
      disp('');
      disp('------------------------------');
    
      % Reset input.
      X = temp;
    
    end
    
    给定示例的输出:

    Input:
        1   10    8    5   10    3    5    2
    
    Output:
        1   10    8   10    3    5    2
    
    Removed elements:
     5
    
    ------------------------------
    Input:
        1   10    8   10    3    5    2
    
    Output:
        1   10    8    3    2
    
    Removed elements:
       10    5
    
    ------------------------------
    Input:
        1   10    8    3    2
    
    Output:
       10    8    3    2
    
    Removed elements:
     1
    
    ------------------------------
    Input:
       10    8    3    2
    
    Output:
     2
    
    Removed elements:
       10    8    3
    
    ------------------------------
    Input:
     2
    
    Output:
    [](1x0)
    
    Removed elements:
     2
    
    ------------------------------
    

    这是一个合适的解决方案,还是我缺少了一些(明显的)低效率?

    X有多大?通常它有多少唯一的元素?让这个过程(我认为是一个函数)也返回删除的元素不是更简单吗?还有,值总是正整数吗?@LuisMendo X通常包含数百个,最多包含数千个,是的值总是正的。@Grasshoper不,我不是建议使用直方图方法。给定两个数组
    X
    Y
    ,找到
    X~=Y
    的第一个元素。这是第一个删除的元素。现在应用于不匹配后的剩余阵列。解为O(kn),其中
    k
    是移除的元素数,
    n
    X
    的长度。不过,这可能比
    histc(unique)
    解决方案建议的速度慢,编码量也多。谢谢。这个解决方案似乎是正确的,但是@Luis mendo提供的解决方案似乎更有效。这个方法很好用,而且很简洁!非常感谢。
    Input:
        1   10    8    5   10    3    5    2
    
    Output:
        1   10    8   10    3    5    2
    
    Removed elements:
     5
    
    ------------------------------
    Input:
        1   10    8   10    3    5    2
    
    Output:
        1   10    8    3    2
    
    Removed elements:
       10    5
    
    ------------------------------
    Input:
        1   10    8    3    2
    
    Output:
       10    8    3    2
    
    Removed elements:
     1
    
    ------------------------------
    Input:
       10    8    3    2
    
    Output:
     2
    
    Removed elements:
       10    8    3
    
    ------------------------------
    Input:
     2
    
    Output:
    [](1x0)
    
    Removed elements:
     2
    
    ------------------------------