繁体   English   中英

在MATLAB中沿一维直方图

[英]Histogram along one dimension in MATLAB

假设我有一个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秒。

您可以使用: histc

x = [0:5:100];
y = histc(A,x, dim); 

其中dim是要计算的维度。

接着

hist(y(:,1),x);
hist(y(:,2),x);
...

将数组A拆分为一个单元格数组,其中每个单元格都是矩阵中的单个列:

Acell = [mat2cell(A',ones(1,M))]';

将使用cellfun的功能cellfun单元格数组Acell每个单元格

counts = cellfun(@(x)histcounts(x,edges),Acell);

counts将是一个单元格数组,每个单元格包含来自A的相应列的历史记录。

您可以使用num2cellcellfun ,尽管我不知道这与幼稚的方法在性能方面的比较。

默认情况下, num2cell接受一个矩阵并将其转换为一个单元格数组,其中每个单元格都包含矩阵的一个元素,但是传递第二个参数允许您沿特定维度进行操作。 因此,对于2x3矩阵Anum2cell(A, 1)将返回1x3单元格数组,其中每个单元格包含A的2×1列。

cellfun将函数应用于单元格的每个元素。 因此,在这种情况下,您可以像上面那样从num2cell获取一个单元格数组C输出, num2cell应用于A每一列,如下所示:

counts = cellfun(@(column) histcounts(column, edges), C);

counts应该是一个3元素的数组,其中第i个元素包含A的第i个列的历史histcounts结果。

(请注意,上面的@()语法是一个匿名函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM