【发布时间】:2016-01-22 05:40:39
【问题描述】:
假设我有一个N×M 矩阵A。我想为A 的每一列计算直方图。天真的方法是做这样的事情:
edges = 0:5:100;
counts = zeros(numel(edges) - 1, M);
for i_c = 1:M
counts(:, i_c) = histcounts(A(:, i_c), edges);
end
有没有更好(更快)的方法来做到这一点?
编辑:添加一些性能测试
好的,让我们做一些测试。首先是histcounts + 循环,然后是使用arrayfun 和索引向量的替代方案,然后是btmcnellis/randomGuy 的解决方案cellfun,最后是obchardon 的解决方案使用histc。
对于长列,histcount 似乎更有效。但是对于较短但较多的列,histc 的优势很大!
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(:))
实际测试:
niter = 100;
M = 10000;
N = 100;
经过的时间是 2.423785 秒。
经过的时间是 2.730303 秒。
经过的时间是 3.774217 秒。
经过的时间是 2.721766 秒。
niter = 10;
M = 100;
N = 10000;
经过的时间是 5.438335 秒。
经过的时间是 7.387587 秒。
经过的时间是 7.647818 秒。
经过的时间是 0.276491 秒。
【问题讨论】:
-
在您的实际情况中
edges是否也是0:5:100? -
@Divakar 我不想排除其他值,但是您对这种特殊情况的建议是什么?
-
好吧,我试图以
5的渐进步长为阈值,然后在沿列的循环中使用 accumarray,但这似乎很慢。所以,我想,选择histc或histcounts。