14
$\begingroup$

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?

$\endgroup$
17
$\begingroup$

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} *)
$\endgroup$
  • 5
    $\begingroup$ I will never know what "along columns" and "along rows" mean. I would have guessed the opposite. $\endgroup$ – Rojo Jan 27 '13 at 0:46
  • $\begingroup$ Thanks! The hard part of Mathematica is knowing the commands! $\endgroup$ – David Kerr Jan 27 '13 at 0:47
  • 2
    $\begingroup$ In the second case, a true mathematician would've transposed the matrix and exultantly said ... $\endgroup$ – Dr. belisarius Jan 27 '13 at 6:39
  • 3
    $\begingroup$ I think you may have confused rows and columns. By default Total sum along the columns. $\endgroup$ – Mr Alpha Jan 27 '13 at 12:19
  • $\begingroup$ @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 :) $\endgroup$ – rm -rf Jan 27 '13 at 14:42
5
$\begingroup$

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

$\endgroup$
  • $\begingroup$ Add colors to the output (so that the numerals are not all black) and you'll get my vote. $\endgroup$ – Mr.Wizard Jan 27 '13 at 3:39
  • 1
    $\begingroup$ Absolutely satisfied. Belated +1! $\endgroup$ – Mr.Wizard Jan 31 '13 at 8:29
4
$\begingroup$
 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} *)
$\endgroup$
  • 1
    $\begingroup$ How do you pick only one column or row? $\endgroup$ – David Kerr Jan 27 '13 at 0:58
  • 1
    $\begingroup$ @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*) ... $\endgroup$ – kglr Jan 27 '13 at 1:09
3
$\begingroup$

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}
*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.