在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];
ones
和zeros
行定义了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];
我想在{{{}中定义a
,b
,c
,d
,e
和f
的比例/频率1}}。
我想最终得到以下列表:
pop
我能想到的一种方法是对行进行求和,然后计算每个行的出现次数,然后进行排序和索引
a = 0.5;
b = 0.1;
c = 0;
d = 0.2;
e = 0;
f = 0.2;
但这并不能让我得到我想要的东西(即当频率= 0时)并且它似乎必须有更快的方式?
答案 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
最后,您需要计算A
中pop
的十进制格式数字,您可以使用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。