我想使用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.
请注意,tic
和toc
没有计时find
,所以这不是问题。
在Rody和njkt的帮助下,我也意识到我的方法并没有真正做到我想要的。我只想用find
找到的组合 i 和 j 更改条目(对于所有 k 和 l ),即[2,4,:,:]
和[6,8,:,:]
,但不是 [2,8,:,:]
和[6,4,:,:]
。在第一个示例中,sum(isnan(M(:)))
应返回16。
答案 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它所以我不知道在这种情况下是否会更快。