Supposons que j'ai une matrice N×M
A
. Je voudrais calculer l'histogramme pour chaque colonne de A
. La manière naïve serait de faire quelque chose comme ceci:Histogramme le long d'une dimension dans MATLAB
edges = 0:5:100;
counts = zeros(numel(edges) - 1, M);
for i_c = 1:M
counts(:, i_c) = histcounts(A(:, i_c), edges);
end
Existe-t-il une meilleure façon (plus rapide) de faire cela?
Edit: Ajouter quelques tests de performance
OK, nous allons faire quelques tests. Première histcounts
+ boucle, puis une alternative en utilisant arrayfun
et un vecteur d'indexation, puis btmcnellis/randomGuy solution avec cellfun
, enfin obchardon solution en utilisant histc
. Il semble que pour de longues colonnes, histcount
est plus efficace. Mais pour les colonnes plus courtes mais beaucoup, histc
gagne par une grande marge!
niter = 10;
M = 100;
N = 10000;
A = rand(M, N);
edges = 0:.05:1;
counts1 = zeros(numel(edges) - 1, N);
counts2 = zeros(numel(edges) - 1, N);
counts3 = zeros(numel(edges) - 1, N);
counts4 = zeros(numel(edges), N);
tic;
for i_r = 1:niter
for i_c = 1:N
counts1(:, i_c) = histcounts(A(:, i_c), edges);
end
end
toc
tic;
for i_r = 1:niter
counts2 = cell2mat(arrayfun(@(ind) histcounts(A(:, ind), edges), 1:size(A, 2), 'UniformOutput', 0)')';
end
toc
tic;
for i_r = 1:niter
Acell = num2cell(A, 1);
counts3 = cell2mat(cellfun(@(column) histcounts(column, edges), Acell, 'UniformOutput', 0)')';
end
toc
tic;
for i_r = 1:niter
counts4 = histc(A, edges, 1);
end
toc
all(counts1(:) == counts2(:))
all(counts1(:) == counts3(:))
counts4 = counts4(1:numel(edges)-1, :); % histc has an extra bin
all(counts1(:) == counts4(:))
essais réels:
niter = 100;
M = 10000;
N = 100;
temps est écoulé 2.423785 secondes.
Le temps écoulé est 2,730303 secondes.
Le temps écoulé est de 3.774217 secondes.
Le temps écoulé est de 2.721766 secondes.
niter = 10;
M = 100;
N = 10000;
temps est écoulé 5.438335 secondes. La durée écoulée est de 7,387587 secondes.
Le temps écoulé est de 7,647818 secondes.
Le temps écoulé est de 0,276491 secondes.
Est-ce que '' 0 edges' être: 5: 100' dans votre cas réel aussi? – Divakar
@Divakar Je ne voudrais pas exclure d'autres valeurs, mais quelle serait votre suggestion pour ce cas particulier? – zeeMonkeez
Eh bien, j'essayais de passer au seuil progressif de '5' et d'utiliser ensuite accumarray dans une boucle le long des colonnes, mais il semble que ce soit plutôt lent. Donc, je suppose, aller avec le 'histc' ou' histcounts'. – Divakar