我有以下606 x 274表: see here
目标:
对于每个日期计算较低和较高的20%百分位数,并根据结果创建2个新变量,例如'L'代表“lower”,'U'代表“upper”,它包含在表格标题中看到的股票代码名称。
一步一步:
% 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);
感谢您的帮助和想法!
答案 0 :(得分:0)
一般来说,如果你有一组数字:
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%百分位数的标题是循环遍历行,删除NaN,获取剩余的排序的余数值并获得20%或80%百分位数的特定指数。遗憾的是,我有一个旧版本的Matlab不支持表格,所以我无法验证标题名称是否正确返回,但这个想法应该是明确的。
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;