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}
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}]
1
s, you can spare the Unitize
, or even use Lenght[lst]-Plus@@lst
. How much faster would that be?
$\endgroup$
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$
Dec 16, 2013 at 0:56
Very straightforward
Count[{0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1},
x_ /; x != 0]
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
Position
,Count
,Cases
and related functions. $\endgroup$Position[{1, 0, 0, 1}, Except[0]?NumericQ, {1}]
andSparseArray[{1, 0, 0, 1}]["NonzeroPositions"]
. $\endgroup$