error using the function 'splitapply'
3 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Alberto Acri
le 30 Nov 2023
Commenté : Alberto Acri
le 30 Nov 2023
Hi! I have a problem about using 'splitapply'.
Using the matrix 'matrix_out_98' the code works, but using the matrix 'matrix_out_12' does not work.
Would anyone be able to help me understand why this?
% matrix_out = importdata("matrix_out_12.mat");
matrix_out = importdata("matrix_out_98.mat");
max_matrix_out = max(matrix_out(:,2));
max_matrix_out_r = floor(max_matrix_out*10)/10;
%Mention the bins to group data in
j = [0 0.1:0.1:max_matrix_out_r Inf];
%Discretize the data
idx2 = discretize(matrix_out(:,2),j);
%Get the sum of the 2nd column according to the groups
out2 = splitapply(@(x) sum(x), matrix_out(:,2), idx2);
Error:
Error using splitapply (line 111)
For N groups, every integer between 1 and N must occur at least once in the vector of group numbers.
2 commentaires
Dyuman Joshi
le 30 Nov 2023
Déplacé(e) : Dyuman Joshi
le 30 Nov 2023
accumarray will be a better fit here.
matrix_out_12 = importdata("matrix_out_12.mat");
matrix_out_98 = importdata("matrix_out_98.mat");
out_12 = fun(matrix_out_12)
out_98 = fun(matrix_out_98)
function out = fun(matrix_out);
max_matrix_out = max(matrix_out(:,2));
max_matrix_out_r = floor(max_matrix_out*10)/10;
%Mention the bins to group data in
j = [0 0.1:0.1:max_matrix_out_r Inf];
%Discretize the data
idx = discretize(matrix_out(:,2),j);
%Get the sum of the 2nd column according to the groups
out = accumarray(idx, matrix_out(:,2), [], @sum);
end
Dyuman Joshi
le 30 Nov 2023
Déplacé(e) : Dyuman Joshi
le 30 Nov 2023
splitapply, as the error message states, requires there to be atleast 1 data element in every bin/group in which the data is discretized.
There's no such requirement with accumarray(), where it fills the gap automatically - with the default value of 0, or manually as the value specified (for example NaN)
Réponse acceptée
Stephen23
le 30 Nov 2023
Modifié(e) : Stephen23
le 30 Nov 2023
S = load('matrix_out_12.mat') % LOAD is better than IMPORTDATA
max_matrix_out = max(S.matrix_out(:,2));
max_matrix_out_r = floor(max_matrix_out*10)/10; % use ROUND(..,1)
j = [0:0.1:max_matrix_out_r,Inf];
idx2 = discretize(S.matrix_out(:,2),j);
Lets check if all of those groups exist in your data:
ismember(1:max(idx2),idx2) % Nope, some don't:
SPLITAPPLY cannot cope with that: it applies the function to every group from 1 to N, it does not know how to apply your function to data if that data simply does not exist.
Use ACCUMARRAY instead, which in contrast will happily replace undefined outputs with a fill value (by default zero, but you can also set the fill value to whatever you want):
out = accumarray(idx2,S.matrix_out(:,2),[max(idx2),1],@sum)
out(end-6:end)
For example, using NaN as the fill value:
out = accumarray(idx2,S.matrix_out(:,2),[max(idx2),1],@sum, NaN)
out(end-6:end)
7 commentaires
Stephen23
le 30 Nov 2023
Modifié(e) : Stephen23
le 30 Nov 2023
"'out1' consists of {A×1 double}, should be {A×2 double}"
So you want both columns. Here is an approach using ARRAYFUN:
load("matrix_out_98.mat")
load("idx1_98.mat")
out = arrayfun(@(n)matrix_out(n==idx1,:),1:max(idx1),'Uni',0)
Checking a few cells:
out{5}
out{9}
Note that often splitting up data make it harder to work with.
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Data Preprocessing dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!