Clear Filters
Clear Filters

Program not generating 0 as expected to turn variable cell to double

2 views (last 30 days)
I got a variable named SNR_BD_Mean_4, as I would like to find the mean in each of the rows in variable SNR_BD_Mean_4, I will need to change it from call to double. The number of each row of cell in SNR_BD_Mean_4 is different thus I will need to add 0 in other rows to make every row with the same size to turn it into a double variable. So, I come up with this code.
Z1 = cellfun(@numel, SNR_BD_Mean_4); % Converting variable from cell to double
Z2 = 9; % From Z1, input the highest number shown in Z1
newZ1 = Z2*ceil(Z1/Z2);
padfun = @(k) [SNR_BD_Mean_4{k} zeros(1, newZ1(k) - Z1(k))];
Z3 = arrayfun(padfun, 1:numel(SNR_BD_Mean_4), 'un', 0);
Z4 = reshape(Z3, size(SNR_BD_Mean_4));
SNR_BD_Mean = cell2mat(Z4);
SNR_BD_Mean(SNR_BD_Mean==0)=NaN;
The code runs well initially, but if there is a row in Z3 where there is no data, that particular row will not copy any 0 causing the size of each row in Z3 is not the same. This caused when Z4 is generated from reshaping Z3 and change from cell to double, the error will be triggered. Is there any method to fix the code so that whenever there is no data in a particular row, the code can still run successfully? Thanks.

Accepted Answer

Voss
Voss on 3 Mar 2024
Edited: Voss on 3 Mar 2024
newZ1 = Z2*ceil(Z1/Z2);
That makes each element of newZ1 the lowest multiple of Z2 greater than or equal to the corresponding element of Z1. The lowest multiple of Z2 greater than or equal to 0 is 0, so any elements of Z1 that are 0 are also 0 in newZ1, and those elements don't get padded in Z3, i.e., they remain 0-length.
Instead just use
newZ1 = Z2;
(or remove newZ1 and use Z2 in its place) to pad everything to length(Z2). Since Z2 is a scalar, you also need to make a slight modification to padfun.
load('SNR_BD_Mean_4.mat')
SNR_BD_Mean_4
SNR_BD_Mean_4 = 3×1 cell array
{0×0 double } {[30.7948 29.3865 27.2683 33.3307 34.8997 32.5726 32.4240 31.0661 34.4111]} {[ 37.5413 38.2187 36.0853 38.1339 37.9931]}
Z1 = cellfun(@numel, SNR_BD_Mean_4)
Z1 = 3×1
0 9 5
% Z2 = 9;
Z2 = max(Z1(:)) % From Z1, input the highest number shown in Z1
Z2 = 9
% compare the old way:
newZ1 = Z2*ceil(Z1/Z2);
padfun = @(k) [SNR_BD_Mean_4{k} zeros(1, newZ1(k) - Z1(k))];
Z3 = arrayfun(padfun, 1:numel(SNR_BD_Mean_4), 'un', 0)
Z3 = 1×3 cell array
{1×0 double} {1×9 double} {[37.5413 38.2187 36.0853 38.1339 37.9931 0 0 0 0]}
% with the new way:
padfun = @(k) [SNR_BD_Mean_4{k} zeros(1, Z2 - Z1(k))];
Z3 = arrayfun(padfun, 1:numel(SNR_BD_Mean_4), 'un', 0)
Z3 = 1×3 cell array
{[0 0 0 0 0 0 0 0 0]} {1×9 double} {[37.5413 38.2187 36.0853 38.1339 37.9931 0 0 0 0]}
Z4 = reshape(Z3, size(SNR_BD_Mean_4));
SNR_BD_Mean = cell2mat(Z4);
SNR_BD_Mean(SNR_BD_Mean==0)=NaN;
disp(SNR_BD_Mean);
NaN NaN NaN NaN NaN NaN NaN NaN NaN 30.7948 29.3865 27.2683 33.3307 34.8997 32.5726 32.4240 31.0661 34.4111 37.5413 38.2187 36.0853 38.1339 37.9931 NaN NaN NaN NaN
  2 Comments
Voss
Voss on 3 Mar 2024
Edited: Voss on 3 Mar 2024
By the way, since you are padding with zeros and then replacing the zeros with NaNs, it would be better to just pad with NaNs in the first place. This way, not only is it fewer steps, but also if there is ever a zero in the original data it would not be erroneously replaced by a NaN.
To do this, simply replace "zeros" with "NaN" in the definition of padfun. (NaN is actually a function that works similarly to the zeros function.)
Yat Chi
Yat Chi on 4 Mar 2024
Thanks very much for your help, now the code runs smoother. Thanks you

Sign in to comment.

More Answers (0)

Categories

Find more on Data Distribution Plots in Help Center and File Exchange

Tags

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!