使用accumarray函数的百分比功能

6

我有两个数组:

OTPCORorder = [61,62,62,62,62,62,62,62,62,62,62,62,65,65,...]
AprefCOR = [1,3,1,1,1,1,1,1,1,1,2,3,3,2,...]

对于 OTPCORorder 中的每个元素,AprefCOR 中都有一个相应的元素。我想知道每组唯一 OTPCORorder 中数字 1 的百分比,如下:

OTPCORorder1 = [61,62,65,...]
AprefCOR1 = [1,0.72,0,...]

我已经有这个了:

[OTPCORorder1,~,idx] = unique(OTPCORorder,'stable');
ANS = OTPCORorder1 = [61,62,65,...];

我曾经使用过"accumarray",但是现在我使用了像下面这样的"mean"或者"sum"函数:

AprefCOR1 = accumarray(idx,AprefCOR,[],@mean).';

我在想是否有一种方法可以使用 "prctile" 函数或任何其他函数,以便在这种情况下给我特定元素的百分比,例如 "1"。非常感谢你。
3个回答

5
这可能是一种方法:
%// make all those non-zero values to zero
AprefCORmask = AprefCOR == 1;

%// you have done this
[OTPCORorder1,~,idx] = unique(OTPCORorder,'stable');

%// Find number of each unique values
counts = accumarray(idx,1);

%// Find number of ones for each unique value
sumVal = accumarray(idx,AprefCORmask);

%// find percentage of ones to get the results
perc = sumVal./counts

Results:
结果:
Inputs:
输入:
OTPCORorder = [61,62,62,62,62,62,62,62,62,62,62,62,65,65];
AprefCOR = [1,3,1,1,1,1,1,1,1,1,2,3,3,2];

输出:

perc =

1.0000
0.7273
     0

@chinkare_16 没问题,顺便说一下,如果你有时间,请接受我们的任何一个答案,无论哪个能更好地解决你的问题。 - Santhan Salai
@SanthanSalai - 因为原帖作者想要通过accumarray方法来解决问题,所以应该接受你的答案,因为你做到了原帖作者的要求。我提供了一种替代方案,因为在这种情况下(至少在我看来),使用accumarray会更慢。 - rayryeng
1
@SanthanSalai,恭喜您成为了一名3000用户...祝贺您 :-) - kkuilla
@kkuilla 哈哈,谢谢 :) - Santhan Salai
1
我不小心点了踩。为了改变我的投票,我必须编辑你的帖子。一旦过了一定的宽限期,就不能更改你的投票了。还忘记点赞了! - rayryeng

4

这是不使用 accumarray 的另一种方法。我认为这种方法更易读:

>> list = unique(PCORorder);
>> counts_master = histc(PCORorder, list);
>> counts = histc(PCORorder(AprefCOR == 1), list);
>> perc = counts ./ counts_master

perc =

    1.0000    0.7273         0

上面代码的工作原理是首先找到PCORorder中唯一的那些元素。接着我们使用histc按照这个明确的列表来计算每个唯一值中有多少个元素。如果你使用更新版本的MATLAB,请改用histcounts,语法相同。 一旦我们找到了每个值在PCORorder中对应的元素总数,我们只需计算与AprefCOR == 1对应的PCORorder元素数量,然后为计算百分比,只需将该列表中的每个条目除以前一个列表中的总元素数即可。
它会给出与accumarray相同的结果,但开销更小。

1
没有使用accumarray是很好的 :) 我们的逻辑最终相似 :) +1 - Santhan Salai
2
@SanthanSalai - 嘿 :) 说实话,去年我和你当时的处境一模一样。我开始在这里写答案...然后从Luis Mendo、Divakar、Amro等人那里学到了很多东西...我通常会写答案,然后那些家伙会建议一些让我的代码看起来很糟糕的东西,哈哈。我很钦佩你开始写答案,并且我开始看到你写作方式中的成熟...从没有使用太多MATLAB函数的答案到使用更多函数并且有更少代码的答案。你取得了很大的进步。继续保持! - rayryeng
1
从你那里听到这样的赞美真是太棒了 :) 全部功劳归于你们。虽然我在Matlab方面还只是个孩子(不到4个月的经验),但我正在尽可能地利用我的假期在这里向你们学习MatLab。可悲的是,假期即将结束,我将不再像现在这样活跃。再次感谢你们的所有帮助 :) - Santhan Salai
2
@SanthanSalai 所以现在是假期吗?我以为每个人都已经开始进展神速,因为他们都像rayryeng一样在凌晨4点就起床了 :-) - kkuilla
2
凌晨四点了:P。我住在加拿大多伦多。 - rayryeng
显示剩余6条评论

3
你的方法是可行的,只需要定义一个适当的匿名函数,用于accumarray。令value = 1为您要计算百分比的值。然后
[~, ~, u] = unique(OTPCORorder); %// labels for unique values in OTPCORorder
result = accumarray(u(:), AprefCOR(:), [], @(x) mean(x==value)).';

作为替代方案,您可以按如下方式使用sparse。生成一个两行矩阵,使每列对应于OTPCORorder中的一个可能值。第一行统计了每个OTPCORorder值在AprefCOR中具有所需值的次数;第二行统计了它没有的次数。
[~, ~, u] = unique(OTPCORorder);
s = full(sparse((AprefCOR==value)+1, u, 1));
result = s(2,:)./sum(s,1);

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