Python frequency of records while combining combinations
Python frequency of records while combining combinations
I've started using python for a pet project as organizing this data was not possible in a program like excel. I hope you can give me some guidance on how to achieve the result I'm looking for. Please excuse my lack of python literacy.
I have the following code, which I have simplified by reducing the number of lists and the number of elements in those lists to make it easier to illustrate.
import itertools
from collections import Counter
a = list(itertools.permutations([32,36,41],3))
b = list(itertools.permutations([36,32,41],3))
c = list(itertools.permutations([19,31,7],3))
fulllist = a+b+c
print(Counter(map(tuple, fulllist)))
which gives the following result:
Counter((32, 36, 41): 2, (32, 41, 36): 2, (36, 32, 41): 2, (36, 41, 32): 2, (41, 32, 36): 2, (41, 36, 32): 2, (19, 31, 7): 1, (19, 7, 31): 1, (31, 19, 7): 1, (31, 7, 19): 1, (7, 19, 31): 1, (7, 31, 19): 1)
This is already quite good but not excatly what I need. Now that I have the first count of each list-combination generated by intertools, I don't care anymore about the order of each element inside of said list. So, the final result I would like to obtain is:
(32, 36, 41): 12
(19, 31, 7): 6
And sorted, just like I have written above.
I feel I might be going in circles and perhaps there's a simpler way to get the result I'm looking for. In reality, my lists have 15 elements in them and I have around 50 of these lists to process.
I hope you can help me with this. Thank you very much in advance.
counts =
, then key = tuple(sorted(inputlist))
and count = math.factorial(len(inputlist))
and counts[key] = counts.get(key, 0) + count
, where `inputlist is one of those three inputs. No need to generate any of the permutations at all.– Martijn Pieters♦
Aug 26 at 15:52
counts =
key = tuple(sorted(inputlist))
count = math.factorial(len(inputlist))
counts[key] = counts.get(key, 0) + count
Side note: the
map(tuple, ...))
is not needed, as all permutations are already tuples. You should really use itertools.chain()
to combine the permutation iterators.– Martijn Pieters♦
Aug 26 at 15:57
map(tuple, ...))
itertools.chain()
For the full 50 lists result, do you produce permutations of length 3, or length 15?
– Martijn Pieters♦
Aug 27 at 13:41
3 Answers
3
If you are not counting permutations (in that case use @Martin's answer), and that was just used to create an example list, just sort to make it clear order does not matter:
>>>print(Counter(tuple(sorted(x)) for x in fulllist))
Counter((32, 36, 41): 12, (7, 19, 31): 6)
If all you need is a count of possible permutations, then just calculate those numbers. That number is simply the factorial of the length of the input:
import math
permutationcount = math.factorial(len(inputlist))
If you are creating permutations that are shorter than len(inputlist)
(say, 3 out of 20), then the formula is n! / (n - k)!
:
len(inputlist)
n! / (n - k)!
n = len(inputlist)
k = 3
permutationcount = math.factorial(n) // math.factorial(n - k)
Of course, when k
is equal to n
, then you divide by 0!, which is 1.
k
n
You can sort the input list, and turn it into a tuple, to create a key into a mapping:
from collections import Counter
def count_permutations(lists, k=None):
counts = Counter()
if k is None:
k = len(lists[0])
for l in lists:
key = tuple(sorted(l))
permutationcount = math.factorial(len(l)) // math.factorial(len(l) - k)
counts[key] += permutationcount
return counts
Demo:
>>> count_permutations(([32,36,41], [36,32,41], [19,31,7]), k=3)
Counter((32, 36, 41): 12, (7, 19, 31): 6)
You don't really need to use a Counter
here of course, but it may be convenient to use one anyway if you need the .most_common()
method and don't want to look up how to sort a dictionary by value.
Counter
.most_common()
c = Counter(map(tuple, fulllist))
l = [ tuple(sorted(i[0])):i[1] for i in c.items()]
for e in l:
print(e)
(32, 36, 41): 2
(32, 36, 41): 2
(32, 36, 41): 2
(32, 36, 41): 2
(32, 36, 41): 2
(32, 36, 41): 2
(7, 19, 31): 1
(7, 19, 31): 1
(7, 19, 31): 1
(7, 19, 31): 1
(7, 19, 31): 1
(7, 19, 31): 1
How is this solving the OPs problem? Where are you collating the numbers into sorted sets?
– Martijn Pieters♦
Aug 26 at 16:05
@MartijnPieters. You are correct. I did not sort the tuples.
– LetzerWille
Aug 26 at 16:18
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.
So the real end result is the counts? Why not just calculate those counts, rather than generate the all those combinations?
– Martijn Pieters♦
Aug 26 at 15:50