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.





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






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.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)