4

How do you find the number of elements in a matrix that are non-zero. For instance, the following matrix has 5 nonzero elements.

{0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1}
Michael E2
  • 235,386
  • 17
  • 334
  • 747
Brig
  • 157
  • 1
  • 4

3 Answers3

11

One can use Unitize and Total. Fast on packed arrays.

SeedRandom[1];
foo = RandomInteger[{0, 2}, 10^6] RandomInteger[{0, 2}, 10^6];

Total @ Unitize @ foo
(* 444089 *)

Total @ Unitize @ foo // timeAvg
(* 0.00950128 *)

Some comparisons:

Length @ SparseArray[foo]["NonzeroPositions"] // timeAvg
(* 0.0154271 *)

Length[foo] - Count[foo, 0] // timeAvg
(* 0.0440302 *)

Count[foo, x_ /; x != 0] // timeAvg
(* 0.358267 *)

Length[Select[foo, # != 0 &]] // timeAvg
(* 0.439782 *)

Timing function:

SetAttributes[timeAvg, HoldFirst]
timeAvg[func_] := 
 Do[If[# > 0.3, Return[#/5^i]] & @@ AbsoluteTiming@Do[func, {5^i}], {i, 0, 15}]
Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • If the non zero elements are always 1s, you can spare the Unitize, or even use Lenght[lst]-Plus@@lst. How much faster would that be? – Peltio Dec 16 '13 at 00:52
  • 1
    If the nonzero entries were all 1, then Total@foo takes 0.00749397 sec. Plus @@ foo takes 0.092115 sec. because Apply (@@) unpacks the array. (foo = RandomInteger[{0, 1}, 10^6] RandomInteger[{0, 1}, 10^6]) – Michael E2 Dec 16 '13 at 00:56
  • Darn packed arrays! There was no such thing when I learned Mathematica, last century! – Peltio Dec 16 '13 at 01:01
  • @Peltio AFAIK they were introduced in version 4 around 1999. – Szabolcs Dec 16 '13 at 01:38
  • @Szabolcs I was talking of the other 98 years of that century. :-) – Peltio Dec 16 '13 at 05:27
4

Very straightforward

Count[{0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1}, 
 x_ /; x != 0]
swish
  • 7,881
  • 26
  • 48
1

One way is to select the nonzero entries and then count how many there are:

lst = {0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1};
Length[Select[lst, # != 0 &]]
5
bill s
  • 68,936
  • 4
  • 101
  • 191