Group Abstract Group Abstract

Message Boards Message Boards

0
|
6.6K Views
|
7 Replies
|
7 Total Likes
View groups...
Share
Share this post:

Most efficient way to count occurences in a list?

Posted 6 years ago

What would be the most efficient way to count occurences in a list L of elements that return True for a given boolean function f? Something like

Length[Select[L,f]] 

works but I'm not sure if it is efficient. The function Count does the trick for patterns but I can't see a way to use it for a function.

POSTED BY: Robert Johansson
7 Replies

For short, concise and general, try CountsBy.

If your data is numeric, and the condition is also numeric, try my BoolEval package. http://szhorvat.net/mathematica/BoolEval

In[199]:= arr = RandomInteger[1000, 10000000];

In[201]:= CountsBy[arr, # > 100 &] // Timing
Out[201]= {5.6509, <|True -> 8991315, False -> 1008685|>}

In[202]:= << BoolEval`

In[203]:= BoolCount[arr > 100] // Timing
Out[203]= {0.356869, 8991315}

To count the ones whose square is less than 100, one would use BoolCount[arr^2 < 100]

BoolEval provides a readable and maintainable syntax to the same type of computation that Sander showed.

POSTED BY: Szabolcs Horvát

This can be done ~5 times faster by using UnitStep:

L=RandomInteger[{0,9},1000000];

RepeatedTiming[Count[L,x_?(#>5&)]]

bool[x_]:=x>5
RepeatedTiming[Count[bool/@L,True]]

RepeatedTiming[Count[L,x_/;x>5]]

RepeatedTiming[Count[Thread[L>5],True]]

RepeatedTiming[Count[UnitStep[5-L],0]]

RepeatedTiming[Fold[#1+Boole[#2>5]&,0,L]]

RepeatedTiming[Total[Boole[#>5]&/@L]]

RepeatedTiming[Total[1-UnitStep[5-L]]]

RepeatedTiming[Length[L] - Total[UnitStep[5 - L]]]

gives me:

{0.474,400314}
{0.4834,400314}
{0.314,400314}
{0.26,400314}
{0.038,400314}
{0.0301,400314}
{0.022,400314}
{0.0067,400314}
{0.0045, 400314}
POSTED BY: Sander Huisman
Posted 6 years ago

This variant is even faster:

Total[Boole[# > 5] & /@ L]
POSTED BY: Hans Milton
Posted 6 years ago
POSTED BY: Hans Milton
POSTED BY: Robert Johansson
POSTED BY: Robert Johansson

May be this helps

L = Table[RandomInteger[{0, 9}], {i, 50}]
Count[L, x_ /; x > 5]

or ( with the L from above )

bool[x_] := x > 5
Count[bool /@ L, x_ /; x == True]
POSTED BY: Hans Dolhaine
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard