3
$\begingroup$

Consider the following table:

tab={{1,0,0,1},{1,0,0,1},{0,1,0,1},{1,0,0,1},{0,0,0,1},{1,0,0,0},{0,1,0,1}}

Could you please tell me whether there is a command which returns the row which is repeated the most times?

Say, for the given example, it is {1,0,0,1}, which is repeated 3 times.

The problem is that first, I have to select unique rows, and second the counting should be made. In my real case, there is a table with 18 columns and $10^4$ rows, so the algorithm is sensitive to performance.

$\endgroup$
3
  • 4
    $\begingroup$ Counts[tab] meet you? $\endgroup$
    – yode
    Aug 22, 2023 at 8:35
  • 5
    $\begingroup$ Tally[l tab ][[1, 1]] $\endgroup$ Aug 22, 2023 at 8:42
  • 1
    $\begingroup$ Commonest @ tab? $\endgroup$ Aug 22, 2023 at 9:31

5 Answers 5

7
$\begingroup$
tab = {{1, 0, 0, 1}, {1, 0, 0, 1}, {0, 1, 0, 1}, {1, 0, 0, 1}, {0, 0, 
   0, 1}, {1, 0, 0, 0}, {0, 1, 0, 1}}

Commonest[tab]

{{1, 0, 0, 1}}

{#, Count[tab, First@#]} &@Commonest[tab]

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

$\endgroup$
7
$\begingroup$
First @ Keys @ ReverseSort @ Counts[tab]

{1, 0, 0, 1}

Or

First @ Normal @ ReverseSort @ Counts[tab]

{1, 0, 0, 1} -> 3

Timings

Timings are more or less equal:

ran = RandomInteger[1, {10^6, 4}];

First @ Keys @ Counts[ran]; // RepeatedTiming // First

0.293924

Tally[ran][[1, 1]]; // RepeatedTiming // First

0.299086

Commonest[ran]; // RepeatedTiming // First

0.297343

MaximalBy[PositionIndex[ran], Length] // RepeatedTiming // First

0.258426

Edit

Since the question is also about performance:

With ParallelTable and running on 4 kernels you get a significant speed gain with:

SeedRandom[1234];
ran = RandomInteger[1, {10^6, 4}];

(a = ReverseSort @ Counts[ran]); // RepeatedTiming // First

0.299939

(b = ReverseSort @ Merge[ParallelTable[
    Counts[Partition[ran, Length[ran]/4][[i]]], {i, 4}], Total]); // RepeatedTiming // First

0.0864523

a == b

True

It should also be noted that Counts and Tally must ReverseSort the result. Commonest and MaximalBy (like their names suggest) deliver an already sorted result. I added ReverseSort to my above answer.

$\endgroup$
6
$\begingroup$
MaximalBy[PositionIndex[tab],Length]

(* <|{1, 0, 0, 1} -> {1, 2, 4}|> *)
$\endgroup$
5
$\begingroup$

Just for variety and to show comparison.MaximalBy as per other users. I have voted for other answers.

f1[u_] := MaximalBy[Tally[u], Last]
f2[u_] := 
 MaximalBy[Reap[Map[Sow[1, {#}] &]@u, _, {#1, Total@#2} &][[2]], 
  Last]
f3[u_] := MaximalBy[{#[[1]], Length@#} & /@ Split[Sort[u]], Last]
f4[u_] := MaximalBy[KeyValueMap[List, GroupBy[u, # &, Length]], Last]

Testing:

test = RandomInteger[{0, 1}, {1000, 18}];
at[u_] := AbsoluteTiming[u[test]]
Grid[{#, at@#} & /@ {f1, f2, f3, f4}]

enter image description here

$\endgroup$
3
$\begingroup$

Another method using GroupBy and Repeated:

MaximalBy[{#[[1]][[1]], #[[2]]} & /@ Normal[GroupBy[tab, Repeated, Length]], Last]

(*{1, 0, 0, 1}*)

Or using GatherByand SortBy:

First@*Last@SortBy[GatherBy[tab, Repeated], Length]

 (*{1, 0, 0, 1}*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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