views:

44

answers:

3

In MATLAB, is there a more concise way to handle discrete conditional indexing by column than using a for loop? Here's my code:

x=[1 2 3;4 5 6;7 8 9];
w=[5 3 2];

q=zeros(3,1);
for i = 1:3
    q(i)=mean(x(x(:,i)>w(i),i));
end
q

My goal is to take the mean of the top x% of a set of values for each column. The above code works, but I'm just wondering if there is a more concise way to do it?

+1  A: 

I don't know of any way to index the columns the way you want. This may be faster than a for loop, but it also creates a matrix y that is the size of x.

x=[1 2 3;4 5 6;7 8 9];
w=[5 3 2];

y = x > repmat(w,size(x,1),1);
q = sum(x.*y) ./ sum(y)

I don't claim this is more concise.

JohnPS
+1  A: 

Here's a way to solve your original problem: You have an array, and you want to know the mean of the top x% of each column.

%# make up some data
data = magic(5);

%# find out how many rows the top 40% are
nRows = floor(size(data,1)*0.4);

%# sort the data in descending order
data = sort(data,1,'descend');

%# take the mean of the top 20% of values in each column
topMean = mean(data(1:nRows,:),1);
Jonas
+1  A: 

You mentioned that you were using the function PRCTILE, which would indicate that you have access to the Statistics Toolbox. This gives you yet another option for how you could solve your problem, using the function NANMEAN. In the following code, all the entries in x less than or equal to the threshold w for a column are set to NaN using BSXFUN, then the mean of each column is computed with NANMEAN:

x(bsxfun(@le,x,w)) = nan;
q = nanmean(x);
gnovice