我试图找出如何在MATLAB中删除矩阵的元素,如果它与任何其他元素的差异为0.01。我应该使用矩阵的所有独特元素作为我正在创建的ROC曲线的阈值,但我需要一种方法来删除彼此在0.01之内的值(因为我们假设它们是如果这是真的,基本上相等。)
非常感谢帮助!
谢谢!
答案 0 :(得分:3)
如果您只是想从矢量中删除该公差范围内的相邻值,我会从这样的事情开始:
roc = ...
tolerance = 0.1;
idx = [logical(1) diff(roc)>tolerance)];
rocReduced = roc(idx);
'rocReduced'现在是一个向量,其中所有值都没有原始向量在容差范围内的相邻值。
这种方法有两个明显的局限性:
我怀疑上述情况还不够。也就是说,我仍然无法想到在使用矢量化矩阵运算时克服这些(和其他)限制的任何简单操作。
如果性能不是一个大问题,您可能会使用以下迭代算法:
roc = ...
tolerance = 0.1;
mask = true(size(roc)); % Start with all points
last = 1; % Always taking first point
for i=2:length(roc) % for all remaining points,
if(abs(roc(i)-roc(last))<tolerance) % If this point is within the tolerance of the last accepted point, remove it from the mask;
mask(i) = false;
else % Otherwise, keep it and mark the last kept
last = i;
end
end
rocReduced = roc(mask);
这可以处理多个连续的子容差区间,而不必全部丢弃。它还处理非单调序列。
MATLAB用户有时会回避迭代解决方案(与矢量化矩阵运算相比),但有时在蛮力性能满足您的需求时找到更优雅的解决方案并不值得。
答案 1 :(得分:1)
让矩阵中的所有元素形成图G =(V,E),使得如果它们之间的差小于0.01,则在两个顶点(u,v)之间存在边。现在,为该图构造一个邻接矩阵,找到具有最大度数的元素。将其删除并将其添加到列表中并从图表中删除它的邻居并重复直到没有任何元素。
CODE:
%% Toy dataset
M = [1 1.005 2 ;2.005 2.009 3; 3.01 3.001 3.005];
M = M(:);
A = false(numel(M),numel(M));
for i=1:numel(M)
ind = abs(M-M(i))<=0.01;
A(i,ind) = 1;
end
C = [];
while any(A(:))
[val ind] = max(sum(A));
C(end+1) = M(ind);
A(A(ind,:),:) = 0;
end
这个运行时为O(n ^ 2),其中矩阵有n个元素。是的,它很慢。
答案 2 :(得分:1)
根据您的描述,您不清楚如何处理一系列价值观(正如已在评论中指出的那样),例如: 0.0 0.05 0.1 0.15 ......以及从矩阵中删除元素的实际含义:将它们设置为零,删除整个列,删除整行?
对于矢量,它看起来像(类似于Adams解决方案)
roc = ...
tolerance = 0.1;
% sort it first to get the similar values in a row
[rocSorted, sortIdx] = sort(roc);
% find the differing values and get their indices
idx = [logical(1); diff(rocSorted)>tolerance)];
sortIdxReduced = sortIdx(idx);
% select only the relevant parts from the original vector (revert sorting)
rocReduced = roc(sort(sortIdxReduced));
代码未经测试,但应该有希望。
答案 3 :(得分:0)
在使用阈值或容差来保持所有足够接近的值之前,您可以使用matlab内置的unique()来减少运行。通常,matlab会尝试加速它们的内置,所以尽量使用尽可能多的内置。