21
$\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$
0

5 Answers 5

27
$\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
  • 8
    $\begingroup$ I will never know what "along columns" and "along rows" mean. I would have guessed the opposite. $\endgroup$ Commented Jan 27, 2013 at 0:46
  • $\begingroup$ Thanks! The hard part of Mathematica is knowing the commands! $\endgroup$ Commented Jan 27, 2013 at 0:47
  • 3
    $\begingroup$ In the second case, a true mathematician would've transposed the matrix and exultantly said ... $\endgroup$ Commented Jan 27, 2013 at 6:39
  • 4
    $\begingroup$ I think you may have confused rows and columns. By default Total sum along the columns. $\endgroup$ Commented Jan 27, 2013 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$ Commented Jan 27, 2013 at 14:42
7
$\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$
2
  • $\begingroup$ Add colors to the output (so that the numerals are not all black) and you'll get my vote. $\endgroup$ Commented Jan 27, 2013 at 3:39
  • 1
    $\begingroup$ Absolutely satisfied. Belated +1! $\endgroup$ Commented Jan 31, 2013 at 8:29
6
$\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$
2
  • 1
    $\begingroup$ How do you pick only one column or row? $\endgroup$ Commented Jan 27, 2013 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$ Commented Jan 27, 2013 at 1:09
4
$\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$
1
  • $\begingroup$ Using dot product is also very efficient: ConstantArray[1,Length[mat]].mat;//AbsoluteTiming mat.ConstantArray[1,Length[mat[[1]]]];//AbsoluteTiming $\endgroup$ Commented Jun 11, 2020 at 8:04
3
$\begingroup$

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

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.