在MATLAB中删除或更改数组中大量条目的最快方法是什么?

时间:2013-09-05 14:26:16

标签: arrays performance matlab nan

我想使用MATLAB将4D数组 M _ ijkl 中的多个值更改为NaN。 我使用find来获取符合 k = 2且 l <的某个条件的索引 i j / em> = 4(在我的情况下,它是 t _4时位置的 y 组件)。我现在想要将这些 i j 组合以及所有 k l 的所有条目设置为NaN

我使用这种方法来做(例如nkjt):

% initialise
M = zeros(10,10,2,4);

% set two points in (:,:,2,4) to be above threshold. 
M(2,4,2,4)=5; 
M(6,8,2,4)=5; 

% find and set to NaN
[i,j] = find(M(:,:,2,4) > 4);
M(i,j,:,:)= NaN;

% count NaNs
sum(isnan(M(:)))   % returns 32

此方法非常慢,如下例所示:

M = rand(360,360,2,4);
threshold = 0.5;

% slow and wrong result
[i,j] = find(M(:,:,2,4) > threshold);
tic;
M(i,j,:,:) = NaN;
toc;

Elapsed time is 54.698449 seconds.

请注意,tictoc没有计时find,所以这不是问题。

在Rody和njkt的帮助下,我也意识到我的方法并没有真正做到我想要的。我只想用find找到的组合 i j 更改条目(对于所有 k l ),即[2,4,:,:][6,8,:,:],但不是 [2,8,:,:][6,4,:,:]。在第一个示例中,sum(isnan(M(:)))应返回16。

2 个答案:

答案 0 :(得分:3)

您检查过结果吗?因为我认为他们错了。例如,如果你有

A = [...
    1 2 3
    4 5 6
    7 8 9];

并且您想要将元素A(1,1)A(2,3)设置为NaN。你在做什么

A([1 2], [1 3]) = NaN

但是这给了

A =
   NaN     2   NaN
   NaN     5   NaN
     7     8     9

最简单快捷的方法是不使用find,而是使用逻辑索引:

M = rand(360,360,2,4);
maximum = 0.05;
tic;
M(M(:,:,2,4) > maximum) = NaN;
toc

在我的电脑上提供:

Elapsed time is 0.003547 seconds.

答案 1 :(得分:2)

重塑M:

让我快得多
M = rand(360,360,2,4);
M = reshape(M,[360*360,2,4]);
maximum = 0.05;
n = find(M(:,2,4) > maximum);

tic;
M(n,:,:) = NaN;
M = reshape(M,[360, 360, 2, 4]);
toc;

ETA:

M(i,j,:,:)= NaN;将所有k,l的i,j的所有组合设置为NaN(如Rody的答案中所述)。

例如:

% initialise
M = zeros(10,10,2,4);

% set two points in (:,:,2,4) to be above threshold. 
M(2,4,2,4)=5; 
M(6,8,2,4)=5; 

% find and set to NaN
[i,j] = find(M(:,:,2,4) > 4);
M(i,j,:,:)= NaN;

% count NaNs
sum(isnan(M(:)))   % returns 32

e.g。 '(2,4,l,k)= NaN'但也'(4,2,l,k)= NaN'。

如果这是你想要的,请在find之后使用unique减小i,j的大小。


在逻辑索引方面,基本上,做A(A>2)=NaN;而不是n = find(A>2); A(n)=NaN;的做法通常更好。在重新塑造的情况下,您可以M(M(:,2,4)>maximum,:,:) = NaN;。我没有tic / toc它所以我不知道在这种情况下是否会更快。