Pirooz
Pirooz

Reputation: 11

How to sum columns of a matrix for a specified number of columns?

I have a matrix A of size 2500 x 500. I want to sum each 10 columns and get the result as a matrix B of size 2500 x 50. That is, the first column of B is the sum of the first 10 columns of A, the second column of B is the sum of second 10 columns of A, and so on.

How can I do that without a for loop? Since I have to do that hundreds of times and it is highly time consuming to do that using for loop.

Upvotes: 1

Views: 275

Answers (2)

Luis Mendo
Luis Mendo

Reputation: 112659

This can be done with splitapply. An advantage of this approach is that it works even if the group size does not divide the number of columns (the last group is smaller):

A = reshape(1:120, 12, 10).'; % example 10×12 data (borrowed from HansHirse)
n_cols = 5; % number of columns to sum over
result = splitapply(@(x)sum(x,2), A, ceil((1:size(A,2))/n_cols));

In this example,

A =
     1     2     3     4     5     6     7     8     9    10    11    12
    13    14    15    16    17    18    19    20    21    22    23    24
    25    26    27    28    29    30    31    32    33    34    35    36
    37    38    39    40    41    42    43    44    45    46    47    48
    49    50    51    52    53    54    55    56    57    58    59    60
    61    62    63    64    65    66    67    68    69    70    71    72
    73    74    75    76    77    78    79    80    81    82    83    84
    85    86    87    88    89    90    91    92    93    94    95    96
    97    98    99   100   101   102   103   104   105   106   107   108
   109   110   111   112   113   114   115   116   117   118   119   120

result =
    15    40    23
    75   100    47
   135   160    71
   195   220    95
   255   280   119
   315   340   143
   375   400   167
   435   460   191
   495   520   215
   555   580   239

Upvotes: 1

HansHirse
HansHirse

Reputation: 18895

First, we "block reshape" A, such that we have the desired number of columns. Therefore, we shamelessly steal the code from the great Divakar, and put in some minimal effort to generalize it. Then, we just need to sum along the second axis, and reshape to the original form.

Here's an example with five columns to be summed:

% Sample input data
A = reshape(1:100, 10, 10).'
[r, c] = size(A);

% Number of columns to be summed
n_cols = 5;

% Block reshape to n_cols, see https://stackoverflow.com/a/40508999/11089932
B = reshape(permute(reshape(A, r, n_cols, []), [1, 3, 2]), [], n_cols);

% Sum along second axis
B = sum(B, 2);

% Reshape to original form
B = reshape(B, r, c / n_cols)

That's the output:

A =
     1     2     3     4     5     6     7     8     9    10
    11    12    13    14    15    16    17    18    19    20
    21    22    23    24    25    26    27    28    29    30
    31    32    33    34    35    36    37    38    39    40
    41    42    43    44    45    46    47    48    49    50
    51    52    53    54    55    56    57    58    59    60
    61    62    63    64    65    66    67    68    69    70
    71    72    73    74    75    76    77    78    79    80
    81    82    83    84    85    86    87    88    89    90
    91    92    93    94    95    96    97    98    99   100

B =
    15    40
    65    90
   115   140
   165   190
   215   240
   265   290
   315   340
   365   390
   415   440
   465   490

Hope that helps!

Upvotes: 3

Related Questions