4
$\begingroup$

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}
$\endgroup$
  • 4
    $\begingroup$ That is not correct Mathematica syntax ... $\endgroup$ – Dr. belisarius Dec 10 '13 at 17:15
  • 1
    $\begingroup$ Look up Position, Count, Cases and related functions. $\endgroup$ – Yves Klett Dec 10 '13 at 17:27
  • 1
    $\begingroup$ Two different ways: Position[{1, 0, 0, 1}, Except[0]?NumericQ, {1}] and SparseArray[{1, 0, 0, 1}]["NonzeroPositions"]. $\endgroup$ – C. E. Dec 10 '13 at 17:32
  • $\begingroup$ I think that @anon has sufficiently interesting answers in comments that this question might be worth fixing and keeping? $\endgroup$ – Verbeia Dec 10 '13 at 19:46
  • $\begingroup$ @Verbeia the question is still ambiguous. Not sure if it is about counting or finding non-zero elements. $\endgroup$ – Yves Klett Dec 10 '13 at 20:47
10
$\begingroup$

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}]
$\endgroup$
  • $\begingroup$ 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? $\endgroup$ – Peltio Dec 16 '13 at 0:52
  • 1
    $\begingroup$ 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]) $\endgroup$ – Michael E2 Dec 16 '13 at 0:56
  • $\begingroup$ Darn packed arrays! There was no such thing when I learned Mathematica, last century! $\endgroup$ – Peltio Dec 16 '13 at 1:01
  • $\begingroup$ @Peltio AFAIK they were introduced in version 4 around 1999. $\endgroup$ – Szabolcs Dec 16 '13 at 1:38
  • $\begingroup$ @Szabolcs I was talking of the other 98 years of that century. :-) $\endgroup$ – Peltio Dec 16 '13 at 5:27
4
$\begingroup$

Very straightforward

Count[{0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1}, 
 x_ /; x != 0]
$\endgroup$
1
$\begingroup$

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
$\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.