3
$\begingroup$

In the following example, I'm trying to how many times each integer 1-n appears in list 'a'. But if an element did not appear in a list, Counts[] creates an association that returns the element instead of zero. So the result is a mixed list of counts and integers, with no indication of which you're looking at.

n = 10;
a = RandomInteger[n, n]
c = Counts[a];
Table[i /. c, {i, 1, n}]

{7, 7, 0, 7, 10, 5, 3, 0, 1, 8}
{1, 2, 1, 4, 1, 6, 3, 1, 9, 1}

Is there a way to make a Counts[] function that can count zero?

$\endgroup$
4
$\begingroup$

Use Lookup instead of ReplaceAll:

n = 10;
SeedRandom[1]
a = RandomInteger[n,n];
c = Counts[a]

Table[i /. c, {i, 1, n}]
Lookup[c, Range[10], 0]

<|1 -> 1, 4 -> 2, 0 -> 4, 7 -> 1, 8 -> 1, 6 -> 1|>

{1, 2, 3, 2, 5, 1, 1, 1, 9, 10}

{1, 0, 0, 2, 0, 1, 1, 1, 0, 0}

$\endgroup$
2
$\begingroup$

Or you can use SparseArray with additive matrix assembly which may be a bit faster:

n = 1000000;
a = RandomInteger[n, n];
counts = Lookup[Counts[a], Range[1, n], 0]; // AbsoluteTiming // First

counts2 = Rest@With[{spopt = SystemOptions["SparseArrayOptions"]},
     Internal`WithLocalSettings[
      SetSystemOptions["SparseArrayOptions" -> {"TreatRepeatedEntries" -> Total}],

      SparseArray[Partition[a+1, 1] -> 1, {n+1}],

      SetSystemOptions[spopt]]
     ]; // AbsoluteTiming // First

1.30965

0.148508

True

$\endgroup$
1
$\begingroup$
a = {7, 7, 0, 7, 10, 5, 3, 0, 1, 8};
Counts[a] /@ Range[10] /. Missing -> (0 &)

{1, 0, 1, 0, 1, 0, 3, 1, 0, 1}

Alternatively,

Block[{Missing = (0 &)}, Counts[a] /@ Range[10]]

{1, 0, 1, 0, 1, 0, 3, 1, 0, 1}

$\endgroup$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.