how do i get MATLAB to extract a specific value in multidimension array or matrix
Show older comments
Hi, i have a matric 420x32x20
then i want to extract the value form -1 to -4
thus, i tried
for i=1:32
for j=1:20
idx(:,i,j)=CHIRPS_SPI3_SM(:,i,j)<-1 & CHIRPS_SPI3_SM(:,i,j)>-4;
end
end
but i came out as 1 and 0 only. But, how can I use MATLAB to extract and save the actual value of -1 till -4?
5 Comments
Walter Roberson
on 20 Apr 2021
The shape of the region that holds data in that range could be irregular. How do you want to represent the irregular region?
Nurul Ain Basirah Zakaria
on 20 Apr 2021
[x, y] = ndgrid(1:32, 1:20);
S_SPI3_SM= (x-16).^2 + (y-10).^2 - 3.5.^2;
idx = S_SPI3_SM < -1 & S_SPI3_SM> -4;
imagesc(idx); colormap(gray(2))
The white area above is where S_SPI3_SM is between -4 and -1. You want to extract the actual values:
actual_values = S_SPI3_SM(idx).'
Is that the output that you would want? Just a list of the numeric values, in linear order relative to the original matrix?
Nurul Ain Basirah Zakaria
on 22 Apr 2021
Walter Roberson
on 22 Apr 2021
Not typically, no. In some cases, the values in the range you want all happen to form a nice hypercube, and in that case you could extract the hypercube. However, most of the time, there will be values that are not wanted that are mixed in with the values that are wanted, and in that case the best you could do would be to find the "bounding box" -- the smallest axis-alighted cuboid that contains all the values you want, but also contains some values that you do not want.
Answers (2)
Matt J
on 20 Apr 2021
idx=CHIRPS_SPI3_SM<-1 & CHIRPS_SPI3_SM>-4;
extractedValues=CHIRPS_SPI3_SM(idx);
Walter Roberson
on 22 Apr 2021
Edited: Walter Roberson
on 22 Apr 2021
If you want the bounding box, then
mask = CHIRPS_SPI3_SM<-1 & CHIRPS_SPI3_SM>-4; %m x n x p
mask1 = any(mask,1); %1 x n x p
mask13 = any(mask1,3); %1 x n x 1
cmin = find(mask13,1,'first');
cmax = find(mask13,1,'last');
mask23 = any(any(mask,2),3); %m x 1 x 1
rmin = find(mask23,1,'first');
rmax = find(mask23,1,'last');
mask12 = any(mask1,2); %1 x 1 x p
pmin = find(mask12,1,'first');
pmax = find(mask12,1,'last');
bounds = [cmin cmax rmin rmax pmin pmax];
subset = CHIRPS_SPI3_SM(cmin:cmax, rmin:rmax, pmin:pmax);
9 Comments
Walter Roberson
on 22 Apr 2021
Edited: Walter Roberson
on 22 Apr 2021
You want to extract the values associated with the locations that are in that particular range, but you also want the result to be a cuboid, even though the locations are scattered.
You have a conflict of purposes, and you will not be able to meet both of those requirements at the same time.
I am going to guess that your third dimension represents time, and that you need to look at all of the time values for any location that falls into the given range for at least one time period.
mask = any(CHIRPS_SPI3_SM<-1 & CHIRPS_SPI3_SM>-4,3); %m x n x 1
mask1 = mask(:);
SPI3_2d = reshape(CHIRPS_SPI3_SM, [], size(CHIRPS_SPI3_SM,3));
selected_SPI3_2d = SPI3_2d(mask1, :);
Now selected_SPI3_2d is a 2D array in which the rows correspond to locations that had -4 to +1 occur at least once, and the columns correspond to time (assuming the third dimension of the data is time.)
You can then process that data however appropriate, and generate a column vector of results
Then you can take your 2D map that you want to overlay the data into, and do
new_map2d = map2d;
new_map2d(mask1) = TheResults;
and then you can view the image new_map2d .
If you have additional reference data that you need to use, then you can use the same kind of techniques to extract it for use in your calculations; for example,
mean_temperature_2d = reshape(mean_temperature, [], size(mean_temperature,3));
selected_mean_temperature = mean_temperature_2d(mask1, :);
Nurul Ain Basirah Zakaria
on 23 Apr 2021
Nurul Ain Basirah Zakaria
on 23 Apr 2021
Walter Roberson
on 23 Apr 2021
If your first dimension is time, then
mask = any(CHIRPS_SPI3_SM<-1 & CHIRPS_SPI3_SM>-4,1); %time x long x lat
mask1 = mask(:);
SPI3_2d = reshape(CHIRPS_SPI3_SM, size(CHIRPS_SPI3_SM,1), :);
selected_SPI3_2d = SPI3_2d(:, mask1);
Now selected_SPI3_2d is a 2D array in which the columns correspond to locations that had -4 to +1 occur at least once, and the rows correspond to time.
You can then process that data however appropriate, and generate a row vector of results, with the columns corresponding to locations.
Then you can take your 2D map that you want to overlay the data into, and do
new_map2d = map2d;
new_map2d(mask1) = TheResults;
This assumes that your map2d is 32 x 20.
Btw sir I cant understand what do you mean by -you also want the result to be a cuboid.
You wanted the results to be directly applied to map locations, so you wanted to have a rectangle of results (or a 3-dimensional equivalent of a rectangle of results), and you wanted that even though some of the areas inside the subset of the map do not have any data that is in the key range.
Nurul Ain Basirah Zakaria
on 23 Apr 2021
Walter Roberson
on 23 Apr 2021
Very odd. Can you try
which reshape
reshape([1 2], [], 1)
to see what happens?
Nurul Ain Basirah Zakaria
on 23 Apr 2021
Walter Roberson
on 23 Apr 2021
No, I mean just plain
reshape([1 2], [], 1)
I want to know if reshape() works for you even in very simple cases.
If not, then use
restoredefaultpath
rehash toolboxcache
Nurul Ain Basirah Zakaria
on 23 Apr 2021
Categories
Find more on Axis Labels in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
