mHelpMe
mHelpMe

Reputation: 6668

summing matrix columns based on another matrix

I have two matrices of the same size.

First matrix: weights 800 x 1250
Second matrix: country_code 800 x 1250

Each column is an observation.

What I would like to do is sum each column in the weights matrix based on the country_code. An example below might explain it better

Weight                          country_code

 20   25  30  15  20        12   12  12  12  12
 40   10  20  5   10        10   10  10  10  10
 10   35  25  50  40        5    5   5   5   5
 30   30  25  30  30        12   12  12  12  12

List of Country Codes      Result Matrix    
 5                         10   35  25  50  40                       
 10                        40   10  20  5   10                 
 12                        50   55  55  45  50

My code is as follows but doesn't give me the correct answers.

int_ccy - is the number of unique country codes
ccy - is a vector of the unique country codes

 for t = 1 : int_ccy
    wgts(t, :) = nansum(Weight(country_code==ccy(t, 1), :));    
 end                 

Upvotes: 0

Views: 46

Answers (3)

Luis Mendo
Luis Mendo

Reputation: 112679

Since all columns of country_code are equal, it can be done in a single line using matrix multiplication.

Let

Weight       = [ 20   25  30  15  20        
                 40   10  20  5   10        
                 10   35  25  50  40        
                 30   30  25  30  30 ];
country_code = [ 12   12  12  12  12
                 10   10  10  10  10
                 5    5   5   5   5
                 12   12  12  12  12 ];

Then

Result = bsxfun(@eq, country_code(:,1).', unique(country_code(:,1))) * Weight;

Upvotes: 2

brodoll
brodoll

Reputation: 1881

Here is one vectorized approach:

%%\ Sample Variables
Weight=[20 25 30 15 20; 40 10 20 5 10; 10 35 25 50 40; 30 30 25 30 30];
country_code=repmat([12;10;5;12],1,4)
list=[5;10;12];

%%\ Sum each column in the weights matrix based on the country_code
[~, countrylines, ~]=intersect(country_code,list)
sum(Weight(countrylines,:),1)

Upvotes: 1

Matt Taylor
Matt Taylor

Reputation: 3408

The following should solve the problem, although there's a nicer way to do it using logical indexing (I think) but I can't recall it off the top of my head:

for t = 1 : int_ccy;
    wgts(t,:) = sum(weight .* (country_code == ccy(t, 1)), 1);    
end  

Upvotes: 1

Related Questions