如何统计矩阵中给定值的元素数量?

74

有人知道如何计算矩阵中某个值出现的次数吗?

例如,如果我有一个1500 × 1的矩阵M(向量),其中存储了星期几的值(1-7),那么如何计算存储在M中有多少个星期日(1)、星期一(2)......星期六(7)?

7个回答

100

1
好的且简单的答案。如果要扩展代码以处理不止一个行矩阵,请使用:sum(sum(your_matrix == 5)) - Alex B.
9
适用于任意维度矩阵的正确扩展应该是 sum(your_matrix(:) == 5) - Dennis Jaheruddin
同时,如果要计算多个值出现的次数,请使用 sum(your_matrix == [1, 2, 3]) - martin jakubik

73

以下是我能想到的计算唯一元素的所有方法列表:

M = randi([1 7], [1500 1]);

选项1:表格化

t = tabulate(M);
counts1 = t(t(:,2)~=0, 2);

Option 2: hist/histc

counts2_1 = hist( M, numel(unique(M)) );
counts2_2 = histc( M, unique(M) );

Option 3: accumarray

counts3 = accumarray(M, ones(size(M)), [], @sum);
%# or simply: accumarray(M, 1);

选项4:排序/差异

[MM idx] = unique( sort(M) );
counts4 = diff([0;idx]);

选项5: arrayfun

counts5 = arrayfun( @(x)sum(M==x), unique(M) );

选项6:bsxfun

counts6 = sum( bsxfun(@eq, M, unique(M)') )';

选项7:稀疏

counts7 = full(sparse(M,1,1));

4
我更喜欢这个答案,而不是那个链接到mathworks的答案,因为它非常清晰且自成体系。 - gakera
@Amro 当 M = [1 2 100000],选项2,counts2_1 = hist( M, numel(unique(M)) )返回的是 [2 0 1],这并不够好,是吧?应该改为 counts2_1 = hist( M, unique(M) ) - Evgeni Sergeev
@EvgeniSergeev:你说得对。HIST的第二个参数可以有不同的含义:1)它可以是标量,表示bin的数量hist(data,nbins)(此时范围为[min(data),max(data)],被分成相等大小的N个bin);2)它也可以指定bin的中心为hist(data,xvalues),假设xvalues是一个均匀间隔的向量;3)或者在向量xvalues不均匀间隔的情况下,连续值之间的中点被用作bin的边缘。 - Amro
在所有三种情况下,hist 中的代码最终都会调用 histc 函数(请检查源代码 edit hist.m,而 histc 是一个内置函数)。因此,我认为最好避免在这里使用 hist,直接使用显式的 bin 边缘调用 histc,就像我上面展示的那样。 - Amro
1
我上面给出的例子大多是针对OP显示的数据而设计的,其中一些方法假定数据值为整数,最好从1开始。请参阅以下答案,了解如何处理更多一般情况:https://dev59.com/ilHTa4cB1Zd3GeqPSYu-#4093228,https://dev59.com/xFnUa4cB1Zd3GeqPe-dy#6933863 - Amro

10

你可以使用函数ACCUMARRAY一次性地对值1到7执行此操作:

>> M = randi(7,1500,1);  %# Some random sample data with the values 1 through 7
>> dayCounts = accumarray(M,1)  %# Will return a 7-by-1 vector

dayCounts =

   218       %# Number of Sundays
   200       %# Number of Mondays
   213       %# Number of Tuesdays
   220       %# Number of Wednesdays
   234       %# Number of Thursdays
   219       %# Number of Fridays
   196       %# Number of Saturdays

5
假设变量 w 包含星期数字([1:7])。
n = histc(M,w)

如果您不知道M中数字的范围:

n = histc(M,unique(M))

这就像是SQL的Group by命令一样!


4

这将非常完美,因为我们正在对矩阵进行操作,而答案应该是一个单一的数字。

sum(sum(matrix==value))

3

这是一个在Matlab中央文件交换平台上可用的非常好的函数文件。

countmember.m 链接

这个函数文件完全向量化,因此非常快。与aioobe回答中提到的函数相比,这个函数不使用accumarray函数,因此即使与较旧版本的Matlab兼容也没有问题。而且,它适用于单元数组和数字数组。

解决方案:

occurrence_count = countmember(unique(M),M)

occurrence_count将是与unique(M)相同大小的数字数组,并且occurrence_count数组的不同值将对应于unique(M)中相应值(相同索引)的计数。


2
使用nnz而非sum。无需将矩阵双折叠为向量,使用nnz可能更快。
nnz(your_matrix == 5)

Doc


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接