How to compress data into numerical intervals

I am trying to compress the water depth data from the given CTD.mat in the following manner.
pwd;
load('pwd\CTD.mat');
A = (1:22).';
for c = 1:21
for cc(c) = CTD.Depth{1, c}(1:end)
for A = 1:22
if cc(c) < 0.5
A = 1;
CTD.Depth2{1, c}(A) = 0;
elseif cc(c) < 1
A = 2;
CTD.Depth2{1, c}(A) = 0.5;
elseif cc(c) < 1.5
A = 3;
CTD.Depth2{1, c}(A) = 1;
elseif cc(c) < 2
A = 4;
CTD.Depth2{1, c}(A) = 1.5;
elseif cc(c) < 2.5
A = 5;
CTD.Depth2{1, c}(A) = 2;
elseif cc(c) < 3
A = 6;
CTD.Depth2{1, c}(A) = 2.5;
elseif cc(c) < 3.5
A = 7;
CTD.Depth2{1, c}(A) = 3
elseif cc(c) < 4
A = 8;
CTD.Depth2{1, c}(A) = 3.5
elseif cc(c) < 4.5
A = 9;
CTD.Depth2{1, c}(A) = 4
elseif cc(c) < 5
A = 10;
CTD.Depth2{1, c}(A) = 4.5
elseif cc(c) < 5.5
A = 11;
CTD.Depth2{1, c}(A) = 5
elseif cc(c) < 6
A = 12;
CTD.Depth2{1, c}(A) = 5.5
elseif cc(c) < 6.5
A = 13;
CTD.Depth2{1, c}(A) = 6
elseif cc(c) < 7
A = 14;
CTD.Depth2{1, c}(A) = 6.5
elseif cc(c) < 7.5
A = 15;
CTD.Depth2{1, c}(A) = 7
elseif cc(c) < 8
A = 16;
CTD.Depth2{1, c}(A) = 7.5
elseif cc(c) < 8.5
A = 17;
CTD.Depth2{1, c}(A) = 8
elseif cc(c) < 9
A = 18;
CTD.Depth2{1, c}(A) = 8.5
elseif cc(c) < 9.5
A = 19;
CTD.Depth2{1, c}(A) = 9
elseif cc(c) < 10
A = 20;
CTD.Depth2{1, c}(A) = 9.5
elseif cc(c) < 10.5
A = 21;
CTD.Depth2{1, c}(A) = 10
else
A = 22;
CTD.Depth2{1, c}(A) = 10.5
end
end
end
end
Please tell me how to fix this code. Also, I would like to compress the salinity data in CTD.mat like the right part of the given image file, can you explain how?

1 Comment

Additional question: 'If the water depth starts from 0.5 m or higher, make the 0 m part NaN and then compress the (depth) / (average salinity) values equally.' -> In this case, what command is needed to put NaN in place of 0 m? Should I use ?

Sign in to comment.

 Accepted Answer

Here's an approach -
%Load the data
load('CTD.mat');
arr = CTD.Depth;
n = numel(arr);
%Pre-allocate the variable in which the output is to be stored
CTD.Sal2 = cell(size(CTD.Sal));
for k=1:numel(arr)
vec = arr{1,k};
%Specify groups to sort data into
%For each set of data maximum value might be differ, so define the bins accordingly
m = ceil(max(vec)/0.5)*0.5;
bins = 0:0.5:m;
%Indices of data sorted according to groups defined
idx=discretize(vec,bins);
%Calculate the mean of the data corresponding to the group indices
CTD.Sal2{1,k} = accumarray(idx, CTD.Sal{1,k}, [], @mean);
end
%Check the value for the 1st array as shown in the image
disp(CTD.Sal2{1,1})
0.1303 0.1037 0.1421 0.2306 0.2723 1.2362 5.3560 8.7040 11.8039 16.3450 18.2737 19.7480 20.6050 21.3095 21.3767

5 Comments

Thank you so much! However, I would like to ask you one more thing. In the depth section, if there is no part corresponding to the part where the original depth is changed to '0m' - where the original depth is less than 0.5m - I would like to insert NaN instead of omitting the 'corresponding to the changed depth 0m' position in Sal2. (Just added a second image that does this.)
As for the additional question, if there are no values for a part/group, you can choose which value to use instead.
Note that I have changed the variable here, from Sal to Temp, as per the image, so I can show the comparison.
%Load the data
load('CTD.mat');
arr = CTD.Depth;
n = numel(arr);
%Pre-allocate the variable in which the output is to be stored
CTD.Temp2 = cell(size(CTD.Temp));
for k=1:numel(arr)
vec = arr{1,k};
%Specify groups to sort data into
%For each set of data maximum value might be differ, so define the bins accordingly
m = ceil(max(vec)/0.5)*0.5;
bins = 0:0.5:m;
%Indices of data sorted according to groups defined
idx=discretize(vec,bins);
%Calculate the mean of the data corresponding to the group indices
%% Fill with NaN for no values corresponding to any group
%% vvv
CTD.Temp2{1,k} = accumarray(idx, CTD.Temp{1,k}, [], @mean, NaN);
end
%Check the value for the 5th array as shown in the image
disp(CTD.Temp2{1,5})
NaN 25.1637 25.0067 24.9443 24.7835 24.6407 24.4175 24.3163 24.2953 24.3550 24.3454 24.2655 24.1381 24.0896 24.0622 24.0068 23.9789 23.9674
It's working! thank you! Can I ask one last question? To create data in CTD.Depth2 like on the left in the second image, can I just replace @mean with a different function handle? If so, what handle do I need?
For that, you can will have need some more manipulation.
Also, I have combined all the operations here -
load('CTD.mat');
arr = CTD.Depth;
n = numel(arr);
%Preallocation
CTD.Sal2 = cell(size(CTD.Sal));
CTD.Temp2 = cell(size(CTD.Temp));
CTD.Depth2 = cell(size(CTD.Depth));
%All commands in a single for loop
for k=1:numel(arr)
vec = arr{1,k};
m = ceil(max(vec)/0.5)*0.5;
bins = (0:0.5:m)';
idx=discretize(vec,bins);
CTD.Sal2{1,k} = accumarray(idx, CTD.Sal{1,k}, [], @mean, NaN);
CTD.Temp2{1,k} = accumarray(idx, CTD.Temp{1,k}, [], @mean, NaN);
CTD.Depth2{1,k} = sign(accumarray(idx, 1, [], [], NaN)).*bins(1:end-1);
end
disp(CTD.Sal2{1,1})
0.1303 0.1037 0.1421 0.2306 0.2723 1.2362 5.3560 8.7040 11.8039 16.3450 18.2737 19.7480 20.6050 21.3095 21.3767
disp(CTD.Temp2{1,5})
NaN 25.1637 25.0067 24.9443 24.7835 24.6407 24.4175 24.3163 24.2953 24.3550 24.3454 24.2655 24.1381 24.0896 24.0622 24.0068 23.9789 23.9674
disp(CTD.Depth2{1,5})
NaN 0.5000 1.0000 1.5000 2.0000 2.5000 3.0000 3.5000 4.0000 4.5000 5.0000 5.5000 6.0000 6.5000 7.0000 7.5000 8.0000 8.5000
Thanks a lot! : - )

Sign in to comment.

More Answers (0)

Categories

Find more on Functions in Help Center and File Exchange

Products

Release

R2023b

Community Treasure Hunt

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

Start Hunting!