How do I use a 2D logical index matrix to change a subset of a 3D array?

9 views (last 30 days)
I have data in a 11x100x11 array. I'm looking for outliers within the subsets along the third dimension, i.e. data(:,:,1), and want to replace them with NaNs. I use the following line:
cond = abs(data(:,:,1)) > threshold;
which produces a 11x100 matrix, cond. Now I'm trying to figure out how to appropriately use cond to index the values I want to change. If I use the following line:
data(cond,1) = NaN;
I get a 1100x100x11 array. How do I index with cond to cover two dimensions of my array?

Accepted Answer

Star Strider
Star Strider on 31 Mar 2015
I’m not exactly sure what you want. Consider a 3D array to be a cube with the third dimension as ‘slices’, or with 11 (11x100) matrices along the third dimension of the cube. So ‘data(:,:,1)’ is the first ‘page’, ‘data(:,:,2)’ the second ‘page’, and so forth through ‘page’ 11.
To illustrate:
data = randi(100, 5, 6, 5); % Create Smaller ‘data’ Matrix
threshold = 75;
Q1_data = data(:,:,1)
cond = abs(data(:,:,1)) > threshold;
Q2_data(cond,1) = NaN;
Q2_data(~cond,1) = Q1_data(~cond);
Q2_data = reshape(Q2_data, size(data,1), size(data,2))
So you probably have to loop through all 11 ‘pages’ and do the same procedure on each one.
  1 Comment
Debra
Debra on 31 Mar 2015
This works, but I would simplify it like this:
data = randi(100, 5, 6, 5); % Create Smaller ‘data’ Matrix
threshold = 75;
Q1_data = data(:,:,1)
cond = abs(data(:,:,1)) > threshold;
Q1_data(cond) = NaN;
data(:,:,1)=Q1_data;

Sign in to comment.

More Answers (2)

James Tursa
James Tursa on 31 Mar 2015
Edited: James Tursa on 31 Mar 2015
data(cond(:)) = nan; % Use linear indexing since target is 1st plane
  3 Comments
James Tursa
James Tursa on 31 Mar 2015
Edited: James Tursa on 31 Mar 2015
My Answer was based on this line, data(cond,1) = NaN, where it looked to me like you only wanted to change the 1st plane. If you wanted to have different thresholds for each plane and apply them separately, then I would have suggested:
thresholds = 11-element threshold vector for each plane
cond = bsxfun(@gt,abs(x),reshape(thresholds,1,1,[]));
data(cond) = nan;
But, frankly, I am still not sure what you are after since I am not sure what you mean by "... each have their own set of conditions ..."
Debra
Debra on 31 Mar 2015
Having different thresholds for each plane is precisely what I meant by "...each have their own set of conditions." This looks interesting, I'll have to play with it.

Sign in to comment.


Sean de Wolski
Sean de Wolski on 31 Mar 2015
Edited: Sean de Wolski on 31 Mar 2015
Why not just use a for loop over slices...?
  2 Comments
Debra
Debra on 31 Mar 2015
I'm going to, but that doesn't address the indexing problem I was curious about. The variable cond is supposed to represent the first and second dimensions of the 3D array, but Matlab treats it as only the first dimension in the line:
data(cond,1) = NaN;
Rogier Westerhoff
Rogier Westerhoff on 26 Mar 2017
I am struggling with the same. It also makes the whole loop quite slow if you have to do this over many pages. Hopefully Mathworks will find a solution for this soon?

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!