考虑一个10 x 10矩阵K的列,比如K(:,1)
我想创建一个10x4二进制矩阵,告诉我们行条目属于哪个四分之一范围。例如
ith row of binary matirx : [ 1 0 0 0 ] => K(i,1)<prctile(K(:,1),25)
我的代码:
%%%
K = randi(10,10);
BINMAT = zeros(size(K,1),4);
y_1 = prctile(K(:,1),25) ;
ID_1 = find(K(:,1) < y_1);
BINMAT(ID_1,1)=1;
y_2 = prctile(K(:,1),50);
ID_2 = find(( K(:,1) > y_1 & K(:,1) < y_2 ));
BINMAT(ID_2,2)=1;
y_3 = prctile(K(:,1),75);
ID_3 = find(( K(:,1) > y_2 & K(:,1) < y_3 ));
BINMAT(ID_3,3)=1;
y_4 = prctile(K(:,1),100);
ID_4 = find((K(:,1) > y_3 & K(:,1) < y_4 ));
BINMAT(ID_4,4)=1;
%%%
如果我不仅要为一列而是为一组列执行此操作,请说A = [1 2 5 6],BINMAT应该有16列(每列K为4)。有更快的速度这样做的方法?
答案 0 :(得分:0)
您可以使用for循环来迭代A
:
K = randi(10,10);
A = [1 2 5 6]; % columns in K to process
BINMAT = zeros(size(K,1), 4*length(A));
cnt = 0; % helper
for col_indx = A
y_1 = prctile(K(:,col_indx),25) ;
ID_1 = find(K(:,col_indx) < y_1);
BINMAT(ID_1, 4*cnt + 1) = 1;
y_2 = prctile(K(:,col_indx),50);
ID_2 = find(( K(:,col_indx) > y_1 & K(:,col_indx) < y_2 ));
BINMAT(ID_2, 4*cnt + 2)=1;
y_3 = prctile(K(:,col_indx),75);
ID_3 = find(( K(:,col_indx) > y_2 & K(:,col_indx) < y_3 ));
BINMAT(ID_3, 4*cnt + 3)=1;
y_4 = prctile(K(:,col_indx),100);
ID_4 = find((K(:,col_indx) > y_3 & K(:,col_indx) < y_4 ));
BINMAT(ID_4, 4*cnt + 4)=1;
cnt = cnt + 1;
end
我注意到BINMAT
的许多行只包含零,因为您发布的代码的值不等于y_1
,y_2
,y_3
和{考虑到{1}}。我认为你应该使用y_4
等等。
答案 1 :(得分:0)
另一个建议:
K = randi(10,10)
p = 25:25:100;
Y = prctile(K, p);
Y = [zeros(1, size(Y, 2)) ;Y];
BINMAT = zeros(size(K, 1), length(p), size(K, 2));
for j = 1:size(K, 2)
for i = 1:length(p)
BINMAT(Y(i, j) <= K(:,j) & K(:, j) <= Y(i+1, j), i, j) = 1;
end
end
然后,BINMAT(:, :, i)
是您为K(:, i)
定义的二进制矩阵。
答案 2 :(得分:0)
Percentile的核心是排序列表中元素的位置。因此,直接使用sort
将提供最有效的解决方案,因为您需要多列中的多个百分位数。
首先,我们需要一种方法将固定箱分配给已排序的位置。这是我认为prctile使用的向量,但是由于10不能均匀地分成4个区域,所以它有点武断。 (换句话说,你将元素3分配给0-25%的bin或25%-50%的bin)? floor(4*(0.5+(0:9).')/10)+1
现在我们只需要对每列进行排序,并将每个原始元素的排序位置分配给其中一个位置。排序的第二个输出完成了大部分工作:
K = randi(10,10);
A = [1 2 5 6]; % columns in K to process
BINMAT = zeros(size(K,1), 4*length(A));
bins = floor(4*(0.5+(0:9).')/10)+1;
[sortedK, idx] = sort(K(:,A));
% The k'th element of idx belongs to the c(k) bin. So now generate the output.
% We need to offset to the correct block of BINMAT for each column
offset_bins = bsxfun(@plus, bins, 4*(0:length(A)-1));
BINMAT(sub2ind(size(BINMAT), idx, offset_bins)) = 1;