Използване на процентна функция с acumarray

Имам два масива:

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", но използвах функцията "mean" или "sum" като тази:

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 - Тъй като OP искаше подход чрез accumarray, отговорът да приемете трябва да бъде ваш, тъй като сте направили това, което OP поиска. Предоставих алтернатива, защото 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
Без акумаррей е добре :) Нашата логика обаче завърши по подобен начин :) +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 - хех :) TBH, миналата година бях в точно същите обувки като теб. Започвах да пиша отговори тук... и започнах да научавам неща от Луис Мендо, Дивакар, Амро и т.н.... Обикновено пишех отговори, след което тези момчета предлагаха нещо, което правеше кода ми да изглежда ужасно хаха. Възхищавам ти се, че започна да пишеш отговори и започвам да виждам зрелостта в начина, по който ги пишеш... от отговори, които не използват много от функциите на 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

Ето решение, използващо sass. Първо инсталирайте обвързванията на python:

pip install sass

След това го използвайте:

import sys
import sass
app = QApplication(sys.argv)

# Create your sass style sheet (you can also write this in a file and load the file)
style = '''
$bg-dark: #292929;

QPushButton {
color: red;
background-color: $bg-dark;
}
'''.encode('utf-8')

# Compile Sass to CSS
style = sass.compile_string(style).decode()

# And set it to your app
app.setStyleSheet(style)
- 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