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$
7
  • 5
    $\begingroup$ That is not correct Mathematica syntax ... $\endgroup$ Commented Dec 10, 2013 at 17:15
  • 1
    $\begingroup$ Look up Position, Count, Cases and related functions. $\endgroup$ Commented Dec 10, 2013 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$ Commented Dec 10, 2013 at 17:32
  • $\begingroup$ I think that @anon has sufficiently interesting answers in comments that this question might be worth fixing and keeping? $\endgroup$ Commented Dec 10, 2013 at 19:46
  • $\begingroup$ @Verbeia the question is still ambiguous. Not sure if it is about counting or finding non-zero elements. $\endgroup$ Commented Dec 10, 2013 at 20:47

3 Answers 3

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.