在matlab中,找到矩阵中唯一行出现的频率

时间:2015-04-09 07:46:15

标签: arrays matlab matrix

在Matlab中,我说有以下矩阵,代表10个人口:

pop = [0 0 0 0 0; 1 1 1 0 0; 1 1 1 1 1; 1 1 1 0 0; 0 0 0 0 0; 0 0 0 0 0; 1 0 0 0 0; 1 1 1 1 1; 0 0 0 0 0; 0 0 0 0 0];

oneszeros行定义了6种不同的“类型”个体。

a = [0 0 0 0 0];
b = [1 0 0 0 0];
c = [1 1 0 0 0];
d = [1 1 1 0 0];
e = [1 1 1 1 0];
f = [1 1 1 1 1];

我想在{{{}中定义abcdef的比例/频率1}}。

我想最终得到以下列表:

pop

我能想到的一种方法是对行进行求和,然后计算每个行的出现次数,然后进行排序和索引

a = 0.5;
b = 0.1;
c = 0;
d = 0.2;
e = 0;
f = 0.2;

但这并不能让我得到我想要的东西(即当频率= 0时)并且它似乎必须有更快的方式?

4 个答案:

答案 0 :(得分:5)

您可以使用pdist2(统计工具箱)获取所有频率:

indiv = [a;b;c;d;e;f]; %// matrix with all individuals
result = mean(pdist2(pop, indiv)==0, 1);

在您的示例中,这给出了

result =
    0.5000    0.1000         0    0.2000         0    0.2000

同样,您可以使用bsxfun手动计算pdist2(pop, indiv)==0,与Divakar's answer一样。


对于您示例中的特定个体(可以通过其数量来识别),您也可以

result = histc(sum(pop, 2), 0:size(pop,2)) / size(pop,1);

答案 1 :(得分:4)

方法#1

使用bsxfun -

A = cat(1,a,b,c,d,e,f)
out = squeeze(sum(all(bsxfun(@eq,pop,permute(A,[3 2 1])),2),1))/size(pop,1)

输出 -

out =
    0.5000
    0.1000
         0
    0.2000
         0
    0.2000

方法#2

如果这些元素是二进制数字,您可以将它们转换为decimal格式。

因此,pop的十进制格式变为 -

>> bi2de(pop)
ans =
     0
     7
    31
     7
     0
     0
     1
    31
     0
     0

在连接数组中,A变为 -

>> bi2de(A)
ans =
     0
     1
     3
     7
    15
    31

最后,您需要计算Apop的十进制格式数字,您可以使用histc计算。A = cat(1,a,b,c,d,e,f) out = histc(bi2de(pop),bi2de(A))/size(pop,1) 。这是代码 -

out =
    0.5000
    0.1000
         0
    0.2000
         0
    0.2000

输出 -

{{1}}

答案 2 :(得分:4)

有一些独特的功能可用于此目的。如果

[q,w,e] = unique(pop,'rows');

q是唯一行的矩阵,w是首先出现在矩阵中的行的索引。第三个元素e包含q的索引,以便pop = q(e,:)。有了这个,问题的其余部分应该是直截了当的。 e中值的概率应该是此行在pop中出现的概率。

可以使用histc

完成计数
histc(e,1:max(e))/length(e)

可以找到

的非出现行
ismember(a,q,'rows')

当然还有其他方式,也许(可能)更快的方式,或oneliners。为什么我发布这是因为它提供了一种易于理解,易读且不需要任何特殊工具箱的方法。

修改 此示例给出了预期输出

a = [0,0,0,0,0;1,0,0,0,0;1,1,0,0,0;1,1,1,0,0;1,1,1,1,0;1,1,1,1,1]; % catenated a-f
[q,w,e] = unique(pop,'rows');
prob = histc(e,1:max(e))/length(e);
out = zeros(size(a,1),1);
out(ismember(a,q,'rows')) = prob;

答案 3 :(得分:4)

我认为ismember是执行此操作的最直接和最通用的方法。如果您的小组更复杂,那么这就是要走的路:

population = [0,0,0,0,0; 1,1,1,0,0; 1,1,1,1,1; 1,1,1,0,0; 0,0,0,0,0; 0,0,0,0,0; 1,0,0,0,0; 1,1,1,1,1; 0,0,0,0,0; 0,0,0,0,0];
groups = [0,0,0,0,0; 1,0,0,0,0; 1,1,0,0,0; 1,1,1,0,0; 1,1,1,1,0; 1,1,1,1,1];

[~, whichGroup] = ismember(population, groups, 'rows');
freqOfGroup = accumarray(whichGroup, 1)/size(groups, 1);

在您的特殊情况下,这些组可以用它们的总和来表示,因此如果这个通用解决方案不够快,请使用sum - histc简化Luis used