1

我想使用 MATLAB将4D数组M_ijkl中的多个值更改为 NaN。find用来获取满足k = 2 和l = 4 特定条件的索引ij(在我的情况下,它是时间t _4位置的y分量)。我现在想将这些ij组合以及所有kl的所有条目设置为 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.

请注意,tic并且toc不要计时,find所以这不是问题。

在 Rody 和 njkt 的帮助下,我也意识到我的方法实际上并没有达到我想要的效果。我只想用我找到的组合ijfind更改条目(对于所有kl),即[2,4,:,:]and [6,8,:,:],但不是 [2,8,:,:]and [6,4,:,:]。在第一个示例中sum(isnan(M(:)))应该返回 16。

4

2 回答 2

3

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

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

并且您想设置 elementA(1,1)A(2,3)to 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.
于 2013-09-05T14:44:17.360 回答
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;

预计到达时间:

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

例如:

% 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

例如'(2,4,l,k) = NaN' 但也有'(4,2,l,k) = NaN'。

如果这是您想要的,请使用 unique after 减小 i,j 的大小find


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

于 2013-09-05T16:34:28.597 回答