2016-03-09 5 views
2

Предположим, у меня есть 3 векторов, вектор A который (n x 1), вектор B который (n x 1) и вектор C который (n x 1).Вложенные двойной сортировки в Matlab

Я хочу сортировать элементы A, в 5 групп, а затем в этих группах я хочу сортировать соответствующие элементы B в 5 группах. А затем возьмите среднее значение элементов в C. Поэтому у меня будет 25 средних значений.

Другими словами:

  1. Сортировка элементы A в 5 квинтилях;
  2. Выберите первую группу элементов в A, получите соответствующие значения в B;
  3. Сортировка выбранных элементов B в 5 групп.
  4. Учитывайте среднее значение для каждой группы от C.
  5. Выберите вторую группу элементов в A, получите соответствующие значения в B;
  6. Сортировка выбранных элементов B в 5 групп.
  7. Учитывайте среднее значение для каждой группы от C.
  8. И так далее и так далее.

Вот мой фиктивный код для этого:

minimum = 50; 
maximum = 100; 

A = (maximum-minimum).*rand(1000,1) + minimum; 
B = (maximum-minimum).*rand(1000,1) + minimum; 
C = (maximum-minimum).*rand(1000,1) + minimum; 


nbins1 = 5; 
nbins2 = 5; 

bins1 = ceil(nbins1 * tiedrank(A)/length(A)); 

for i=1:nbins1 

    B1 = B(bins1==i); 
    C1 = C(bins1==i); 
    bins2 = ceil(nbins1 * tiedrank(B1)/length(B1)); 

    for j=1:nbins2 
     C2 = C1(bins2==j); 
     output(i,j) = mean(C2); 
     clearvars C2 
    end 


    clearvars B1 C1 
end 

Вопрос заключается в том, что это, кажется, не очень элегантно и эффективным на всех. Есть ли другой способ сделать это? Для людей в области финансов эта проблема аналогична двойной сортировке портфелей Fama-French (1993).

ответ

0

Прежде всего, сортировать все по колонке А:

sortedByA = sortrows([A,B,C], 1); 

Создать фиктивный вектор, представляющий показатели каждой группы А (от 1 к nbins1):

groupsA = repmat(1:nbins1, 1000/nbins1, 1); groupsA = groupsA(:); 

Затем пересортировывать снова (по первым двум столбцам), но заменяя фактический столбец А групповыми индексами, что фактически будет относить В в каждой группе значений в А:

sorted = sortrows([groupsA, sortedByA(:,[2,3])], [1,2]); 

Создание индексов для групп в колонке C (от 1 до nbins1*nbins2):

groupsC = repmat(1:(nbins1*nbins2), 1000/(nbins1*nbins2), 1); groupsC = groupsC(:); 

Наконец, вычислить означает, в каждой группе:

averages = accumarray(groupsC, sorted(:,3), [], @mean); 
+0

@volcompt, могли бы вы принять ответ, если он решает твоя проблема? –

Смежные вопросы