在matlab中寻找向量中的删除元素
我有一个过程,是迭代和随机修剪一个巨大的整数向量,我想找出哪些元素在每次迭代之间被删除。这个向量有很多重复,使用ismember()和setdiff()对我帮助不大 作为说明,如果X=[1,10,8,5,10,3,5,2]:在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
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
xM
的中间矩阵,其中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
------------------------------