Использование процентной функции с accumarray

У меня есть два массива:

OTPCORorder = [61,62,62,62,62,62,62,62,62,62,62,62,65,65,...]
AprefCOR = [1,3,1,1,1,1,1,1,1,1,2,3,3,2,...]

для каждого элемента в OTPCORorder есть соответствующий элемент в AprefCOR. Я хочу знать процент числа 1 для каждого набора уникальных OTPCORorder следующим образом:

OTPCORorder1 = [61,62,65,...]
AprefCOR1 = [1,0.72,0,...]

У меня уже есть это:

[OTPCORorder1,~,idx] = unique(OTPCORorder,'stable');
ANS = OTPCORorder1 = [61,62,65,...];

и я работал с «accumarray», но я использовал функцию «среднее» или «сумма», например:

AprefCOR1 = accumarray(idx,AprefCOR,[],@mean).';

Мне просто интересно, существует ли способ использовать это, но с функцией «prctile» или любой другой функцией, которая дает мне процент определенного элемента, например «1», в этом случае.

Большое спасибо.


person chinkare_16    schedule 04.06.2015    source источник


Ответы (3)


Это может быть один подход:

%// make all those non-zero values to zero
AprefCORmask = AprefCOR == 1;

%// you have done this
[OTPCORorder1,~,idx] = unique(OTPCORorder,'stable');

%// Find number of each unique values
counts = accumarray(idx,1);

%// Find number of ones for each unique value
sumVal = accumarray(idx,AprefCORmask);

%// find percentage of ones to get the results
perc = sumVal./counts

Результаты:

Входные данные:

OTPCORorder = [61,62,62,62,62,62,62,62,62,62,62,62,65,65];
AprefCOR = [1,3,1,1,1,1,1,1,1,1,2,3,3,2];

Вывод:

perc =

1.0000
0.7273
     0
person Santhan Salai    schedule 04.06.2015
comment
@chinkare_16 добро пожаловать. Кстати, когда у вас есть время, примите любой из наших ответов, который вы когда-либо чувствовали себя лучше, удовлетворив вашу проблему. - person Santhan Salai; 04.06.2015
comment
@SanthanSalai - Поскольку ОП хотел получить подход через accumarray, ответ на принятие должен быть вашим, поскольку вы сделали то, что просил ОП. Я предоставил альтернативу, потому что accumarray в этом случае (по крайней мере, на мой взгляд) будет медленнее. - person rayryeng; 04.06.2015
comment
@SanthanSalai, и теперь вы 3k пользователь... Поздравляю :-) - person kkuilla; 04.06.2015
comment
@kkuilla LOL Спасибо :) - person Santhan Salai; 04.06.2015
comment
Я случайно проголосовал против. Чтобы изменить свой голос, мне пришлось отредактировать ваш пост. Это не позволит вам изменить свой голос по истечении определенного льготного периода. Забыл тоже проголосовать! - person rayryeng; 05.06.2015

Вот еще один подход без использования accumarray. Я думаю, что это более читабельно:

>> list = unique(PCORorder);
>> counts_master = histc(PCORorder, list);
>> counts = histc(PCORorder(AprefCOR == 1), list);
>> perc = counts ./ counts_master

perc =

    1.0000    0.7273         0

Как работает приведенный выше код, так это то, что мы сначала находим те элементы в PCORorder, которые уникальны. Как только мы это сделаем, мы сначала подсчитаем, сколько элементов принадлежит каждому уникальному значению в PCORorder через histc использование корзин для подсчета в качестве точного списка. Если вы используете более новую версию MATLAB, вместо этого используйте histcounts. ... тот же синтаксис. Как только мы находим общее количество элементов для каждого значения в PCORorder, мы просто подсчитываем, сколько элементов соответствует PCORorder, где AprefCOR == 1, а затем, чтобы вычислить процент, вы просто делите каждую запись в этом списке на общее количество элементов из предыдущего список.

Это даст вам те же результаты, что и accumarray, но с меньшими затратами.

person rayryeng    schedule 04.06.2015
comment
Без accumarray хорошо :) Наша логика закончилась похоже :) +1 - person Santhan Salai; 04.06.2015
comment
Спасибо :) accumarray великолепен, но если вы серьезно хотите использовать его для подсчета значений в 1D, histc на самом деле быстрее. - person rayryeng; 04.06.2015
comment
Да я согласен. :) Все еще учусь у вас, ребята, чтобы сделать вещи эффективными: D - person Santhan Salai; 04.06.2015
comment
@SanthanSalai - хех :) ТБХ, в прошлом году я был точно в той же обуви, что и ты. Я начал писать ответы здесь... и я начал учиться у Луиса Мендо, Дивакара, Амро и т. д.... Обычно я писал ответы, а потом эти ребята предлагали что-то, что делало мой код ужасным, лол. Я восхищаюсь вами за то, что вы начали писать ответы, и я начинаю видеть зрелость в том, как вы их пишете... от ответов, в которых не использовалась большая часть функций MATLAB, до использования большего их количества и получения ответов с меньшим количеством кода. . Вы добились больших успехов. Так держать! - person rayryeng; 04.06.2015
comment
Это отличный комплимент от вас :) Полный кредит вам, ребята. Все еще ребенок в Matlab (‹4 месяца опыта). Хотя я максимально использую свои каникулы, изучая MatLab здесь от вас, ребята, к сожалению, каникулы вот-вот закончатся. Больше не будет таким активным. Еще раз спасибо всем за помощь :) - person Santhan Salai; 04.06.2015
comment
Некоторое время назад я сделал несколько тестов для моего личного интереса по этому @mean результату по сравнению с другими альтернативами, но никогда не приводил их здесь. Я мог бы сделать это в ближайшее время. - person Divakar; 04.06.2015
comment
@SanthanSalai Я согласен с rayryeng. Вы делаете большие успехи! Так держать! - person Luis Mendo; 04.06.2015
comment
@LuisMendo Спасибо. Это много для меня значит :) - person Santhan Salai; 04.06.2015
comment
@SanthanSalai Так это праздник? Я думал, что все добились значительного прогресса, потому что они вставали в 4 утра, как rayryeng :-) - person kkuilla; 04.06.2015
comment
@kkuilla да, ты прав. Для меня это были 3 месяца летних каникул, и они вот-вот закончатся :( вы знаете его часовой пояс? Для него может быть не 4 утра :P - person Santhan Salai; 04.06.2015
comment
Было 4 утра :P. Я живу в Торонто, Канада. - person rayryeng; 04.06.2015

Ваш подход работает, вам нужно только определить соответствующую анонимную функцию. для использования accumarray. Пусть value = 1 будет значением, процент которого вы хотите вычислить. затем

[~, ~, u] = unique(OTPCORorder); %// labels for unique values in OTPCORorder
result = accumarray(u(:), AprefCOR(:), [], @(x) mean(x==value)).';

В качестве альтернативы вы можете использовать sparse следующим образом. Сгенерируйте матрицу из двух строк, чтобы каждый столбец соответствовал одному из возможных значений в OTPCORorder. Первая строка подсчитывает, сколько раз каждое значение в OTPCORorder имело желаемое значение в AprefCOR; вторая строка подсчитывает, сколько раз это не так.

[~, ~, u] = unique(OTPCORorder);
s = full(sparse((AprefCOR==value)+1, u, 1));
result = s(2,:)./sum(s,1);
person Luis Mendo    schedule 04.06.2015