2012-05-30 2 views
2

Пусть у меня есть векторы:Matlab: «группировка среднее»

y = [1 1.01 1.02 1.03 2 2.01 2.02 3 3.01 3.02 3.03]; 
c = [0 0 0 0 1 1 1 2 2 2 2 ]; 

Есть ли Векторизованный способ получить «группирование среднего», то есть среднее значение y для каждого уникального значения c? (Это упрощенный пример: у меня что-то похожее, но размер вектора в тысячах и сотни значений c)

Я могу сделать это в цикле, просто интересно, можно ли его векторизовать. Вот мой для цикла реализации:

function [my,mc] = groupmean(y,c) 
my = []; 
mc = []; 
for ci = unique(c)' 
    mc(end+1) = ci; 
    my(end+1) = mean(y(c==ci)); 
end 

ответ

6

Короткий ответ:

>> y = [1 1.01 1.02 1.03 2 2.01 2.02 3 3.01 3.02 3.03]; 
>> c = [0 0 0 0 1 1 1 2 2 2 2 ]; 
>> groupmeans = accumarray(c'+1,y',[],@mean) 
groupmeans = 
     1.015 
     2.01 
     3.015 

Для объяснения выше: accumarray немного загадочно, но очень полезно и стоит того, чтобы знать (и очень быстро). Первый вход представляет собой вектор (они должны быть векторами столбцов, поэтому это c' и y'), который группирует строки второго входного вектора. Элементы должны быть целыми положительными (по какой-то причине), поэтому я добавил 1 к c'. Последний вход - это дескриптор функции, которая применяется в качестве аккумулятора для каждой группы значений в y.

Надеюсь, что имеет смысл! Если нет, doc accumarray :)

+0

круто! благодаря! Похоже, что я мог бы также использовать индекс, возвращенный из 'unique' в качестве первого аргумента для накопителя (например, если мои уникальные значения не были целыми целыми числами) –

+0

@JasonS: или использовать' grp2idx' из набора инструментов статистики – Jonas

+0

@JasonS Да, это звучит правильно. –

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