4

I have a 150 by 300 binary matrix. I would like to find the total amount of zeros in the matrix. I've been consulting online documentation for support, but am unable to use the "count" function properly (I only see how to apply it to a list). Perhaps there is also a better way to do this than using count. When providing a solution, I'd appreciate if you can state what the code is doing, so I can better understand. For the sake of simplicity, I will paste a smaller matrix (5 by 10), but the one I will be applying it to will be 150 by 300. Thanks in advance for your time.

binarym = ({
{1, 1, 1, 0, 0, 0, 0, 0, 1, 1},
{1, 1, 1, 1, 0, 0, 0, 1, 1, 1},
{1, 1, 0, 0, 0, 0, 1, 1, 1, 1},
{1, 1, 1, 1, 0, 0, 0, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 0, 1, 1}})
Astroturf
  • 281
  • 1
  • 4

4 Answers4

14
ClearAll[countZ]
countZ = 1 ## & @@ Dimensions @ # - Total[#, 2] &;
countZ@binarym

17

Timings:

SeedRandom[1]
binm = RandomInteger[{0, 1}, {10000, 10000}];

countZ @ binm // AbsoluteTiming

{0.23863, 49996224}

Wavelets`CountZeros@binm // AbsoluteTiming

{0.520381, 49996224}

(Length @ # - Total @ #) & @ Flatten @ binm // AbsoluteTiming (* Okkes Dulgerci *)

{1.02773, 49996224}

Tr[Flatten@binm] // AbsoluteTiming (* Yves Klett comment *)

{1.06958, 50003776}

Total[1 - binm, 2] // AbsoluteTiming (* illan comment *)

{2.1557, 49996224}

Count[binm, 0, 2] // AbsoluteTiming  (* eyeorbl *)

{6.14531, 49996224}

Times @@ Dimensions[binm] - Total@Flatten@binm // AbsoluteTiming (* Bob Hanlon  comment*)

{9.2004324, 49996224}

Plus @@ Flatten[binm] // AbsoluteTiming (* Yves Klett comment *)

{19.32956, 50003776}

Length @ DeleteCases[Flatten @ binm, 0] // AbsoluteTiming

{25.07808, 50003776}

Length @ Select[Flatten[binm], # == 0 &] // AbsoluteTiming  (* bill s *)

{54.19553, 49996224}

kglr
  • 394,356
  • 18
  • 477
  • 896
  • 1## & (for Times) from @Mr.Wizard somewhere on this site. – kglr Jan 02 '18 at 05:54
  • 2
    Slightly tangential, but if binm is given as a SparseArray then I get almost an order of magnitude speed up for countZ. – aardvark2012 Jan 02 '18 at 10:11
  • 2
    @aardvark2012 First, I was somewhat surprised but did you count in the conversion into a SparseArray? But thinking of it, I recalled that the constructor for sparse arrays has to count the nonzero values. So if you don't count in the construction time, then Times @@ Dimensions[binm] - Length[binm["NonzeroValues"] returns the result for arbitrary large SparseArrays that fit into memory. – Henrik Schumacher Jan 02 '18 at 16:25
  • This 1 ## & @@ in the code is really cool +1! – mgamer Jan 02 '18 at 18:31
  • @HenrikSchumacher No, I didn't count the conversion time (which is bad). I was thinking more that if the original binarym could be constructed as a SparseArray from the outset with no additional cost then it could be well worth it. OP didn't mention how the array was built, so that may not be possible (which is why my comment is "tangential"). I forgot about NonzeroValues, though, which would be a pretty awesome way to do this, if the OP could get it as a SparseArray. – aardvark2012 Jan 02 '18 at 22:17
  • @mgamer thanks for making me smile. :-) – Mr.Wizard Jan 03 '18 at 17:09
4
Count[binarym, 0, 2]

Set the levelspec to 2 because you are interested in the 0s in the lists nested within the outer list.

There's a number of other ways to do this too:

(* Flatten it first *)
Count[Flatten[binarym], 0]

(* Find all of the zeros and then count how many there were *)
Length[Position[binarym, 0]]

(* Count the number of 0s in each row using an anonymous function
   and then total them up. *)
Total[Count[#,0]&/@binarym]

And several others, which have already been mentioned in the comments to your question. Unless you have very strict performance requirements, any of these should work on a 150 by 350 matrix.

eyorble
  • 9,383
  • 1
  • 23
  • 37
4
(Length@# - Total@#) &@Flatten@binarym
OkkesDulgerci
  • 10,716
  • 1
  • 19
  • 38
2

Select all the zeros and then find out how many of them there are:

Length@Select[Flatten[binarym], # == 0 &] 

This gives 17, which is the expected answer.

bill s
  • 68,936
  • 4
  • 101
  • 191