选择在第一个四分位数内排名的值,并将它们标记为逻辑“1'

时间:2014-11-06 08:54:01

标签: matlab

例如,问题的简化版本:

A =

 0      10     50
 20     30     20
 10     70     20
 40     20     10

我想获得每列的逻辑标签,其中值在第一四分位数(L)第二和第三四分位数(M)中排名),和第四四分位数(N)。所以最终我可以得到这样的输出:

L =

 1      1      0
 0      0      0
 0      0      0
 0      0      1

M =

 0      0      0
 1      1      1
 1      0      1
 0      1      0

N =

 0      0      1
 0      0      0
 0      1      0
 1      0      0

在这个4x3矩阵示例中,每列有4个值。第一个四分位数(等级)意味着价值最低的那个,第二个和第三个四分位数将取第二个和第三个最低值,第四个四分位数将是具有最高价值的四分位数。所以,在另一个例子中,如果一列有40个值,那么我想标记' 1'对于矩阵中第一个四分位数的最低10个值,依此类推。

想象一下,我有1000x1000矩阵....'分位数'和'百分位'函数不能这样做,因为它们不对每个单元格值进行排名。那么,我应该做些什么呢?

2 个答案:

答案 0 :(得分:3)

这是你在找什么?:

pL = prctile(A,25,1);
pU = prctile(A,75,1);

L = bsxfun(@le, A, pL);
N = bsxfun(@ge, A, pU);
M = ones(size(A))-L-N;

修改 如果存在NaN,请将其用于M而不是上述内容:

M = ~isnan(A)-L-N;

答案 1 :(得分:2)

q = prctile(A, [25,75,100])

 5   15   15
30   50   35
40   70   50

我们可以使用bsxfun查找以下各点之下的所有数字:

B = bsxfun(@le, A, permute(q, [3,2,1]);

现在你需要将每个矩阵(沿着第三个维度)与前一个矩阵的~(即B(:,:,2) = B(:,:,2).*~B(:,:,1))进行累加,你可以用循环做或者你可以对它进行矢量化像这样:

N = cat(3, ones(size(B,1), size(B,2)), ~B(:,:,1:end-1))
B.*N

返回:

ans(:,:,1) =

 1      1      0
 0      0      0
 0      0      0
 0      0      1

ans(:,:,2) =

 0      0      0
 1      1      1
 1      0      1
 0      1      0

ans(:,:,3) =

 0      0      1
 0      0      0
 0      1      0
 1      0      0

如果要查找不同百分位数的索引,此方法可以非常容易地扩展:

p = [25, 75, 100];
q = prctile(A, p);
B = bsxfun(@le, A, permute(q, [3,2,1]);
N = cat(3, ones(size(B,1), size(B,2)), ~B(:,:,1:end-1))
B.*N

因此,如果您想在五分位数中使用它,只需将p更改为[20 40 60 80 100]