1
$\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$
  • $\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 '16 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$ – CrypticParadigm Jun 11 '16 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 '16 at 16:22
2
$\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$
  • $\begingroup$ Any thoughts on performance of different methods? for big lists... $\endgroup$ – BlacKow Jun 11 '16 at 16:26
  • $\begingroup$ Thank you, March and @Kuba. I can't wait to know as much as you all. $\endgroup$ – CrypticParadigm Jun 11 '16 at 16:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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