2
$\begingroup$

I am trying to make a computation with a large set of rows. As a sample, suppose I have a list of numbers with rows and columns like such:

A =
4   1   3   1   3
2   3   2   4   1
2   2   4   3   2
3   2   4   3   2
1   2   4   2   3
4   1   3   2   2
2   2   2   1   2
2   1   2   4   3
1   3   2   1   1
3   4   3   3   4
3   1   4   2   2

In Mathematica code this would look like

A = {{4, 1, 3, 1, 3}, {2, 3, 2, 4, 1}, {2, 2, 4, 3, 2}, {3, 2, 4, 3, 2},
     {1, 2, 4, 2, 3}, {4, 1, 3, 2, 2}, {2, 2, 2, 1, 2}, {2, 1, 2, 4, 3},
     {1, 3, 2, 1, 1}, {3, 4, 3, 3, 4}, {3, 1, 4, 2, 2}}

I would like to create a tally or find the most common row of numbers with the same number of numbers.

Particularly, the order of numbers does not matter. So for example, 4 1 3 1 3,3 4 1 3 1,1 1 3 3 4 and any combination of these numbers or set of unordered numbers are all equivalent. I am trying to count how many rows have the number 3 occur 2 times, the number 1 occur 2 times, and the number 4 occur 1 time. In the list A it appears that this unordered set only occurs once.

Furthermore, the unordered set 3 1 4 2 2 occurs 5 times (If a counted correctly).

I would like to create a tally from the initial list A which will have the size of n x 5

Any pointers, guidance, or suggestions is greatly appreciated, thank you.

$\endgroup$
3
  • $\begingroup$ Please include your list in Mathematica code so that it easy to copy and paste. As it is, we can't tell where one row ends and another begins. Anyway look up Tally. $\endgroup$
    – march
    Jun 11, 2016 at 15:57
  • $\begingroup$ I am familiar with the call Tally, but I don't know how to incorporate it given this situation of unordered sets. $\endgroup$ Jun 11, 2016 at 16:10
  • $\begingroup$ CountsBy[A, Sort]? But this - " I am trying to count how many rows have the number 3 occur 2 times, the number 1 occur 2 times, and the number 4 occur 1 time" is something different, isn't it? $\endgroup$
    – Kuba
    Jun 11, 2016 at 16:22

1 Answer 1

3
$\begingroup$

I am assuming that your list of lists looks something like

SeedRandom[1]
RandomInteger[{1, 3}, {10, 5}]
(* {{2, 1, 2, 2, 1}, {1, 1, 2, 1, 1}, {1, 1, 3, 1, 2},
    {3, 1, 1, 2, 2}, {1, 1, 2, 1, 3}, {1, 2, 2, 3, 3},
    {1, 2, 1, 2, 1}, {2, 1, 1, 3, 1}, {3, 3, 1, 2, 3}, {2, 3, 1, 1, 1}} *)

Then, we can Tally using a SameTest that doesn't care about order:

Tally[lst, Sort[#1] === Sort[#2] &]
(* {{{2, 1, 2, 2, 1}, 1}, {{1, 1, 2, 1, 1}, 1},
    {{1, 1, 3, 1, 2}, 4}, {{3, 1, 1, 2, 2}, 1},
    {{1, 2, 2, 3, 3}, 1}, {{1, 2, 1, 2, 1}, 1}, {{3, 3, 1, 2, 3}, 1}} *)

Alternatively, Sort the elements first:

Tally[Sort /@ lst]
(* {{{1, 1, 2, 2, 2}, 1}, {{1, 1, 1, 1, 2}, 1},
    {{1, 1, 1, 2, 3}, 4}, {{1, 1, 2, 2, 3}, 1},
    {{1, 2, 2, 3, 3}, 1}, {{1, 1, 1, 2, 2}, 1}, {{1, 2, 3, 3, 3}, 1}} *)

Or, use GroupBy and make an Association (as pointed out by Kuba in a comment do the OP, this can be done more succinctly using CountsBy):

assoc = Length /@ GroupBy[lst, Sort]
(* <|{1, 1, 2, 2, 2} -> 1, {1, 1, 1, 1, 2} -> 1,
     {1, 1, 1, 2, 3} -> 4, {1, 1, 2, 2, 3} -> 1,
     {1, 2, 2, 3, 3} -> 1, {1, 1, 1, 2, 2} -> 1, {1, 2, 3, 3, 3} -> 1|>

What's nice about this is that you can then call the Association with various inputs and spit out the number:

assoc[{1, 1, 1, 2, 3}]
assoc[{1, 1, 1, 1, 1}]
(* 4 *)
(* Missing["KeyAbsent", {1, 1, 1, 1, 1}] *)
$\endgroup$
2
  • $\begingroup$ Any thoughts on performance of different methods? for big lists... $\endgroup$
    – BlacKow
    Jun 11, 2016 at 16:26
  • $\begingroup$ Thank you, March and @Kuba. I can't wait to know as much as you all. $\endgroup$ Jun 11, 2016 at 16:57

Your Answer

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

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