简体   繁体   中英

Matlab - computing the probability of each element within a vector

I am having a vector y which may have the following form:

y = [1 1 1 1 2 2 2 2 1 1 3 3 4 5]

And I want to attach a probability to each element within y as it would've been generated by a random variable. In this case, the element 1 would have the probability 6/14, the element 2 would have the probability 4/14, the element 3 the value 2/14 and the elements 4 and 5 the value 1/14.

And basically, the result should look like:

prob_y = 1/14 * [6 6 6 6 4 4 4 4 6 6 2 2 1 1]

Is there a way of doing this without any for or while loops?

The unique elements in your input vector can be determined using the UNIQUE function. You can then get the desired output using ARRAYFUN and an anonymous function that checks the number of each unique element in your input vector:

>> y = [1 1 1 1 2 2 2 2 1 1 3 3 4 5];
>> prob_y = arrayfun(@(x)length(find(y==x)), unique(y)) / length(y)

prob_y =

    0.4286    0.2857    0.1429    0.0714    0.0714

Create a histogram with as many bins as the difference between your min & max element (plus one to get total range), then normalize by dividing by the number of elements in you original vector.

Something like this:

y = [1 1 1 1 2 2 2 2 1 1 3 3 4 5]
p = hist(y, max(y) - min(y) + 1) / length(y)

[Edit] To answer your updated question: use y to select the indices from p , like this:

prob_y = p(y)

Here is an example using ACCUMARRAY :

y = [1.3 1 1 1 2 2 2 2 1 1 3 3 4 5];

[g,~,gl] = grp2idx(y);
count = accumarray(g,1);
p = count(g) ./ numel(g)

The probabilities:

>> [y(:) p]
ans =
          1.3     0.071429
            1      0.35714
            1      0.35714
            1      0.35714
            2      0.28571
            2      0.28571
            2      0.28571
            2      0.28571
            1      0.35714
            1      0.35714
            3      0.14286
            3      0.14286
            4     0.071429
            5     0.071429

You can see a summary of occurrences as:

>> [gl count]
ans =
            1            5
          1.3            1
            2            4
            3            2
            4            1
            5            1

Note that I am using GRP2IDX to handle cases like 1.3 or integers not starting at 1 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM