2015-07-18 80 views
-1

我有一個數據集,表示許多技術報告的作者列表。每個報告可以由一個或多個人員進行創作:查找列表中列表中出現次數最多的對

a = [ 
['John', 'Mark', 'Jennifer'], 
['John'], 
['Joe', 'Mark'], 
['John', 'Anna', 'Jennifer'], 
['Jennifer', 'John', 'Mark'] 
] 

我已經找到了最常見的對,那就是,人們在過去大多數的合作:

['John', 'Jennifer'] - 3 times 
['John', 'Mark'] - 2 times 
['Mark', 'Jennifer'] - 2 times 
etc... 

怎麼辦這在Python中?

+7

通過編寫一些Python。你有什麼嘗試? – IanAuld

+1

恩,我可能會從某種[Counter]開始(https://docs.python.org/2/library/collections.html#collections.Counter) – NightShadeQueen

+0

不幸的是,我什至不知道如何從這裏開始。我能想到的唯一方法是構建一個巨大的數組,但我猜想有更有效的方法 – paginated

回答

2

使用collections.Counter字典與itertools.combinations

from collections import Counter 
from itertools import combinations 

d = Counter() 
for sub in a: 
    if len(a) < 2: 
     continue 
    sub.sort() 
    for comb in combinations(sub,2): 
     d[comb] += 1 

print(d.most_common()) 
[(('Jennifer', 'John'), 3), (('John', 'Mark'), 2), (('Jennifer', 'Mark'), 2), (('Anna', 'John'), 1), (('Joe', 'Mark'), 1), (('Anna', 'Jennifer'), 1)] 

most_common()將在最常見的順序返回配對到最低,你想要的第一n最常見只是通過nd.most_common(n)

+1

@ kasra,歡呼聲。 –

+0

謝謝。我也喜歡其他解決方案,但是這也是對數據進行排序。 – paginated

+0

@paginated,無後顧之憂,一個反字典是非常適合你想要的 –

1
import collections 
import itertools 

a = [ 
['John', 'Mark', 'Jennifer'], 
['John'], 
['Joe', 'Mark'], 
['John', 'Anna', 'Jennifer'], 
['Jennifer', 'John', 'Mark'] 
] 


counts = collections.defaultdict(int) 
for collab in a: 
    collab.sort() 
    for pair in itertools.combinations(collab, 2): 
     counts[pair] += 1 

for pair, freq in counts.items(): 
    print(pair, freq) 

輸出:

('John', 'Mark') 2 
('Jennifer', 'Mark') 2 
('Anna', 'John') 1 
('Jennifer', 'John') 3 
('Anna', 'Jennifer') 1 
('Joe', 'Mark') 1 
1

您可以使用一組的理解,打造一個集所有數字,然後使用列表理解算在你的子列表中的姓名對發生:

>>> from itertools import combinations as comb 
>>> all_nam={j for i in a for j in i} 
>>> [[(i,j),sum({i,j}.issubset(t) for t in a)] for i,j in comb(all_nam,2)] 

[[('Jennifer', 'John'), 3], 
[('Jennifer', 'Joe'), 0], 
[('Jennifer', 'Anna'), 1], 
[('Jennifer', 'Mark'), 2], 
[('John', 'Joe'), 0], 
[('John', 'Anna'), 1], 
[('John', 'Mark'), 2], 
[('Joe', 'Anna'), 0], 
[('Joe', 'Mark'), 1], 
[('Anna', 'Mark'), 0]] 
+1

'sum({i,j} .issubset(t))...'會做同樣的事情 –

+0

@PadraicCunningham是啊!好主意 ;) – Kasramvd