tags:

views:

66

answers:

4

How can I use the function FIND to count the number of items of a given value instead of using a loop? For example, in the array item below there are 3 occurrences of the number 23, 2 occurrences of the number 22, and 2 occurrences of the number 20.

....
for i=2:n
    if item(i-1)~=item(i)
        nItem21(i)=1;
    else 
        nItem21(i)=nItem21(i-1)+1;
    end
end

item Num
23   2
23   4
23   6
22   3
22   1
20   6
20   8
+4  A: 

You can do the following: identify where the value of item changes, then use diff to get the counts.

item = [
23   
23   
23   
22   
22   
20   
20];

% find the 'last' entries of each consecutive group of numbers
chgRowNum = [find(item(1:end-1) ~= item(2:end);length(item)]; 

counts = diff([0;chgRowNum]);

correspondingItems = item(chgRowNum);
Jonas
thanks you Jonas :)
Jessy
+2  A: 

Find returns the indices of nonzero elements in an array. If you want a count of all the occurrences of your elements (assuming they're integers), you can use the hist function. By assigning an output, it won't plot a histogram. Instead it will return an array of occurrences.

x=[20 23 20 22 23 21 23 22];
bins=min(x):max(x);
count=hist(x,bins);
list=unique(x);

Now count contains the number of occurrences, and list contains each unique array element. To get rid of zero count elements:

idx=find(count);
count=count(idx);

or the one line option (without using find):

count=count(count~=0);
Doresoom
+2  A: 

Just for completeness I would use the histc function.

item = [
23   
23   
23   
22   
22   
20   
20];
%get the unique items
[uni_items, minds, uinds] = unique(item);
%count them
counts = histc(uinds, 1:numel(uni_items));
%put them in the original order
ocounts = counts(minds);

This takes care of them not being in order or if they're not integers.

JudoWill
+2  A: 

Another option for this situation is to use the function ACCUMARRAY, which wouldn't require that the list be sorted first. This is particularly useful if you were to have a set of numbers in item that span a range of 1:N, where N is any integer value. Here's how it would work for your example:

item = [23; 23; 23; 22; 22; 20; 20];  %# A column vector of integers
counts = accumarray(item,1);          %# Collect counts of each item into
                                      %#   a 23-by-1 array

The array counts is a 23-by-1 array where the elements indexed by 23, 22, and 20 contain the counts 3, 2, and 2, respectively. All the other elements are 0 (i.e. there are no counts found for the numbers 1 through 19 or 21).

If you want to get a list of the unique values in item and their corresponding counts, you can do this using the function UNIQUE:

>> uniqueValues = unique(item)  %# Get the unique values in item

uniqueValues =

    20
    22
    23

>> counts = counts(uniqueValues)  %# Get just the counts for each unique value

counts =

     2
     2
     3
gnovice

related questions