20

I have a list of rows in database such as

{{a,b,c}, {d,e,f},{g,h,i}}

I want to be able to add each row across and each column down (like a spreadsheet). In other words be able to pick columns and rows and add down or across.
Could you point me in the right direction?

rm -rf
  • 88,781
  • 21
  • 293
  • 472
David Kerr
  • 583
  • 1
  • 4
  • 11

5 Answers5

26

Use Total with the appropriate second argument to sum the matrix along rows/columns.

Sum along rows:

m = {{a,b,c}, {d,e,f},{g,h,i}};
Total[m, {1}]
(* {a + d + g, b + e + h, c + f + i} *)

By default, Total[m] (without a second argument) sums along the rows.

Sum along columns

Total[m, {2}]
(* {a + b + c, d + e + f, g + h + i} *)
rm -rf
  • 88,781
  • 21
  • 293
  • 472
  • 8
    I will never know what "along columns" and "along rows" mean. I would have guessed the opposite. – Rojo Jan 27 '13 at 00:46
  • Thanks! The hard part of Mathematica is knowing the commands! – David Kerr Jan 27 '13 at 00:47
  • 3
    In the second case, a true mathematician would've transposed the matrix and exultantly said ... – Dr. belisarius Jan 27 '13 at 06:39
  • 4
    I think you may have confused rows and columns. By default Total sum along the columns. – Mr Alpha Jan 27 '13 at 12:19
  • @MrAlpha I guess it depends on what one means by "along the columns". As with Rojo, I can never seem to remember what the right/current/popular interpretation is, but since this is binary, just flip it accordingly :) – rm -rf Jan 27 '13 at 14:42
7

You could get both the row and column sums at once with a simple function:

rowColSum[m_?MatrixQ] := {Plus @@@ m, Plus @@@ Transpose@m}

m = ArrayReshape[Range@6, {2, 3}]

{{1, 2, 3}, {4, 5, 6}}

rowColSum@m

{{6, 15}, {5, 7, 9}}

If you were interested in getting spreadsheet-like output, you could do it this way:

tabulate[m_?MatrixQ] := Module[{rs, cs},
  rs = Plus @@@ m;
  cs = Append[Plus @@@ Transpose@m, ""];
  Append[MapThread[Append, {m, rs}], cs]]

tabulate@m // TableForm

enter image description here

Update

I would like to satisfy Mr.Wizard's request for color, but his specifications were rather vague. I hope the following will satisfy him.

colorPattern = (_RGBColor | _GrayLevel | _Hue);

wizardStyleTabulate[m_?MatrixQ, dataColor : colorPattern : Black, sumColor : colorPattern : Blue] := Module[{data, rs, cs}, data = Map[Style[#, dataColor] &, m, {-1}]; rs = Style[#, sumColor] & /@ Plus @@@ m; cs = Style[#, sumColor] & /@ Append[Plus @@@ Transpose@m, ""]; Append[MapThread[Append, {data, rs}], cs]]

m // wizardStyleTabulate // TableForm

default-styled-image

wizardStyleTabulate[m, Red, Hue[0.55]] // TableForm

styled-image

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
6
 m = {{a, b, c}, {d, e, f}, {g, h, i}};

Update: Tr

Tr /@ (m\[Transpose])       (* column sums *)
Tr[m, Plus, 1]              (* column sums *)
Tr/@m                       (* row sums    *)
Tr[m\[Transpose], Plus, 1]  (* row sums    *)

Column sums

Total@m 
Plus @@ m 
Fold[Plus, First@m, Rest@m]
ConstantArray[1, 3].m 
Flatten@ListConvolve[{ConstantArray[1, 3]}, Transpose@m]
(* {a+d+g, b+e+h, c+f+i} *)

Row sums

Total /@ m
Plus @@@ m
Fold[Plus, First@#, Rest@#] &[Transpose@m]
m.ConstantArray[1, 3]
Flatten@ListConvolve[{ConstantArray[1, 3]}, m]
(* {a+b+c, d+e+f, g+h+i} *)
kglr
  • 394,356
  • 18
  • 477
  • 896
  • 1
    How do you pick only one column or row? – David Kerr Jan 27 '13 at 00:58
  • 1
    @DavidKerr, Total@m[[2]] (* sum of row 2 *), Total@m[[All, 2]] (* sum of column 2 *), and Total@m[[All, {2, 3}]] (* sum of column 2 and sum of column 3*) ... – kglr Jan 27 '13 at 01:09
4

Here are undocumented internal functions for the tasks, which are efficient on numeric arrays.

Packed:

mat = RandomReal[1, {300000, 200}];                           (* rows >> columns *)
Statistics`Library`MatrixColumnSum[mat]; // RepeatedTiming
Total[mat]; // RepeatedTiming

Statistics`Library`MatrixRowSum[mat]; // RepeatedTiming
Total[mat, {2}]; // RepeatedTiming
(*
  {0.038, Null}
  {0.213, Null}

  {0.025, Null}
  {0.061, Null}
*)

mat = RandomReal[1, {300, 200000}];                           (* columns >> rows *)
Statistics`Library`MatrixColumnSum[mat]; // RepeatedTiming
Total[mat]; // RepeatedTiming

Statistics`Library`MatrixRowSum[mat]; // RepeatedTiming
Total[mat, {2}]; // RepeatedTiming
(*
  {0.029, Null}
  {0.132, Null}

  {0.0266, Null}
  {0.0287, Null}
*)

Unpacked:

mat = Developer`FromPackedArray@RandomReal[1, {30000, 200}];  (* rows >> columns *)
Statistics`Library`MatrixColumnSum[mat]; // RepeatedTiming
Total[mat]; // RepeatedTiming

Statistics`Library`MatrixRowSum[mat]; // RepeatedTiming
Total[mat, {2}]; // RepeatedTiming
(*
  {0.062, Null}
  {1.6, Null}     <-- For real???

  {0.047, Null}
  {0.649, Null}
*)

mat = Developer`FromPackedArray@RandomReal[1, {300, 20000}];  (* columns >> rows *)
Statistics`Library`MatrixColumnSum[mat]; // RepeatedTiming
Total[mat]; // RepeatedTiming

Statistics`Library`MatrixRowSum[mat]; // RepeatedTiming
Total[mat, {2}]; // RepeatedTiming
(*
  {0.065, Null}
  {0.079, Null}

  {0.0445, Null}
  {0.625, Null}
*)
Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • Using dot product is also very efficient: `ConstantArray[1,Length[mat]].mat;//AbsoluteTiming

    mat.ConstantArray[1,Length[mat[[1]]]];//AbsoluteTiming`

    – chyanog Jun 11 '20 at 08:04
3

Since V 12.2 we have ArrayReduce

From the documentation:

"Array reduction, also called array aggregation, is used to compute functions such as Mean, Total or StandardDeviation along specific dimensions of an array."

mat =
  {{a, b, c},
   {d, e, f},
   {g, h, i}};

1. Apply a function along rows

ArrayReduce[f, mat, 2]

gives

{f[{a, b, c}],
 f[{d, e, f}],
 f[{g, h, i}]}

This corresponds to

ArrayReduce[Total, mat, 2] == Total[mat, {2}]

(* True *)

and

f /@ mat == ArrayReduce[f, mat, 2]

(* True *)

2. Apply a function along columns

ArrayReduce[f, mat, 1]

{f[{a, d, g}], f[{b, e, h}], f[{c, f, i}]}

This replaces Map and Transpose:

ArrayReduce[f, mat, 1] == Map[f] @ Transpose[mat]

(* True *)

3. AggregationLayer

For deeply nested lists we have AggregationLayer, for which I gave some examples here:

Elegant operations on matrix rows and columns

eldo
  • 67,911
  • 5
  • 60
  • 168