如何使用百分位函数进行排名? (Matlab)

How to use the Percentile Function for Ranking purpose? (Matlab)

我有以下 606 x 274 table: see here


目标:

对于每个日期,计算上下 20% 的百分位数,并根据结果创建 2 个新变量,例如"lower" 的 'L' 和 "upper" 的 'U',其中包含在 table.[=13= 的 header 中看到的代码名称]

一步一步:

% Replace NaNs with 'empty' for the percentile calculation (error: input to be cell array)
     T(cellfun(@isnan,T)) = {[]}
% Change date format
     T.Date=[datetime(T.Date, 'InputFormat', 'eee dd-MMM-yyyy')];
% Take row by row 
     for row=1:606
% If Value is in upper 20% percentile create new variable 'U' that contains the according ticker names.
% If Value is in lower 20% percentile create new variable 'L' that contains the according ticker names.
     end;

到目前为止,对 'prctile' 的试验仅产生了单列的数字结果。示例:

Y = prctile(T.A2AIM,20,2);

感谢您的帮助和想法!

一般来说,如果你有一个数字数组:

a = [4 2 1 8 -2];

可以通过首先对数组进行排序然后尝试访问百分位数中提供的索引来计算百分位数。所以 prctile(a,20) 的功能原则上可以被

取代
b = sort(a);
ind = round(length(b)*20/100);
if ind==0
    ind = 1;
end
b = b(ind);
% b = -2

但是,prctile 对输入向量进行插值以获得受数组大小影响较小的值,这有点神奇。但是,您可以使用上面的想法来找到百分位数拆分列。如果你选择像我上面说的那样做,你想要得到对应于 20% 和 80% 百分位数的 headers 是遍历行,删除 NaNs,得到 indeces对剩余值进行排序并获得 20% 或 80% 百分位数的特定索引。遗憾的是,我有一个旧版本的 Matlab 不支持表格,所以我无法验证 header 名称是否正确返回,但思路应该很清楚。

L = cell(size(T,1),1);
U = cell(size(T,1),1);
for row=1:size(T,1)
    row_values = T{row,:};
    row_values = row_values(2:end); % Remove date column
    non_nan_indeces = find(~isnan(row_values));
    if not(isempty(non_nan_indeces))
        [row_values,sorted_indeces] = sort(row_values(non_nan_indeces));
        % The +1 is because we removed the date column
        L_ind = non_nan_indeces(sorted_indeces(1:round(0.2*length(row_values))))+1;
        U_ind = non_nan_indeces(sorted_indeces(round(0.8*length(row_values)):end))+1;
        % I am unsure about this part
        L{row} = T.Properties.VariableNames(L_ind);
        U{row} = T.Properties.VariableNames(U_ind);
    else
        L{row} = nan;
        U{row} = nan;
    end
end;

如果你想使用 matlab 的 prctile,你必须找到返回值的索引,做这样的事情:

L = cell(size(T,1),1);
U = cell(size(T,1),1);
for row=1:size(T,1)
    row_values = T{row,:};
    row_values = row_values(2:end); % Remove date column
    non_nan_indeces = find(~isnan(row_values));
    if not(isempty(non_nan_indeces))
        [row_values,sorted_indeces] = sort(row_values(non_nan_indeces));
        L_val = prctile(row_values(non_nan_indeces),20);
        U_val = prctile(row_values(non_nan_indeces),80);
        % The +1 is because we removed the date column
        L_ind = non_nan_indeces(sorted_indeces(find(row_values<=L_val)))+1;
        U_ind = non_nan_indeces(sorted_indeces(find(row_values>=U_val)))+1;
        % I am unsure about this part
        L{row} = T.Properties.VariableNames(L_ind);
        U{row} = T.Properties.VariableNames(U_ind);
    else
        L{row} = nan;
        U{row} = nan;
    end
end;