Reputation: 25
I am looking for a way to count occurency in a 2D List. For example I have a list like that:
[[John, 3],[Chris, 3],[Bryan,5],[John,3],[John,7]]
As an output I want to count which numbers does John have most common like that
Most common number for the John is: 3
I did it for all the names easily with
Counter(my_list[1]).most_common(5)
Does anyone have a suggestion to do it?
Upvotes: 0
Views: 264
Reputation: 36838
If you are 100% sure that there always will be exactly 1
most-frequent element for each name, you migth sort
by name, groupby
by name and then use statistics.mode
following way:
import itertools
import statistics
some_data = [['John', 3],['Chris', 3],['Bryan',5],['John',3],['John',7]]
sorted_data = sorted(some_data,key=lambda x:x[0]) # sort by name
most_frequent = {name:statistics.mode(j[-1] for j in list(data)) for name,data in itertools.groupby(sorted_data,key=lambda x:x[0])}
print(most_frequent) # {'Bryan': 5, 'Chris': 3, 'John': 3}
itertools.groupby
returns pairs of name-data, but as data
s itself contain both key (name in our case) and value (number in our case) we need comprehension to get "raw" values.
Upvotes: 0
Reputation: 870
You could also do filtering and mapping:
my_list = [['John', 3],['Chris', 3],['Bryan',5],['John',3],['John',7]]
print(Counter(map(lambda y: y[1], filter(lambda x: x[0] == "John", my_list))).most_common(1))
Upvotes: 0
Reputation: 23684
I would probably re-shape the input data before doing queries on it. Maybe name vs values:
name_lookup = defaultdict(list)
for name, value in my_list:
name_lookup[name].append(value)
name = 'John'
most_common, _ = Counter(name_lookup[name]).most_common(1)[0]
print(f"Most common number for {name} is: {most_common}")
Upvotes: 1
Reputation: 5200
This should work.
from collections import Counter
main_list = [['John', 3],['Chris', 3],['Bryan',5],['John',3],['John',7]] #your_list
new_list = [i[1] for i in main_list if i[0]=='John']
print(Counter(new_list).most_common(1)[0][0])
Upvotes: 1