How to compress data into numerical intervals

8 views (last 30 days)
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
영택 조
영택 조 on 2 Oct 2023
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

Dyuman Joshi
Dyuman Joshi on 2 Oct 2023
Edited: Dyuman Joshi on 2 Oct 2023
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
Dyuman Joshi
Dyuman Joshi on 2 Oct 2023
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

Sign in to comment.

More Answers (0)

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!