2012-06-01 68 views
5

實際上,我有一個關於「會議」的數據集。 例如,A,B,C有一個會議,那麼列表將是[A,B,C]。 像這樣,每個列表將包含參與會議的成員列表。 因此:Python:計算列表中元素對的頻率

LINE1 =(A,B,C)

LINE2 =(A,C,d,E)

line3中=(d,F,G)

..

我只想計算一下每個成員之間相遇的次數。 例如,成員A從line1和line2兩次遇見C,而成員B從line1遇到C一次。所以,我想提出這樣一個圖表..

A B C D E F G... 

A . 1 2 1 ... 

B 1 . 1 0 

C 

...

我認爲這將是很容易在第一,但我很困惑。 請提前幫助我,謝謝你。

+1

學習如何乘以矩陣的時間... –

回答

0

這是一個非常簡單的二維數組或字典的數據結構問題。如果你有很多人,陣列效率會更高,但我會假設你沒有。

times_met = defaultdict(int) 
for line in lines: 
    for pair in itertools.combinations(line, 2) 
     times_met[pair] += 1 

# How many times person a meets person b is described by the following (s.t. a < b) 
print times_met[(a, b)] 

請注意,如果您有大量會議並且可能存在更高效的算法,那麼這非常低效。

+1

我認爲元組的字典 - > int會更有意義 - 所以'people_met [(person1,person2)]'是它們之間的會議。然後它不需要是'defaultdict' - 只需從'itertools.combinations'初始化它。 – lvc

+0

@lvc'defaultdict(int)'語義上更有意義。如果有新用戶加入數據集,可以詢問他曾與其他人會面多少次,並且得到正確的答案 - 0 - 而不是「KeyError」。用零初始化也是非Pythonic。你從來不需要'defaultdict',但它可以讓你編寫更好的代碼。 – agf

+0

編輯是好的,但對於大型數據集來說,這仍然是低效的,因爲您生成的是自己的直線的笛卡爾乘積,而不僅僅是組合。請記住,Python是包含電池 - 已經有一種方法可以做到這一點。 – agf

0

它看起來像你應該能夠解決這個矩陣加法。如果你知道總人數(問題中的G),那麼你的答案將是一個GxG矩陣。創建與從第1行的一個組合矩陣GXG,然後添加與從第2行的一個組合矩陣GXG等

7

與其手動求和的頻率,使用與collections.counter沿itertools

from collections import Counter 
from itertools import chain, combinations 

meets = Counter(chain.from_iterable(combinations(line, 2) for line in lines)) 

哪裏lines是可迭代的名稱迭代。

+0

使用Python庫的+1。一切都在那裏。 >:P –

+0

+1對於一個非常明顯的自我表現的解決方案我踢自己不知道它,直到你的答案。當另一個答案使用'defaultdict(int)'並且'd [item] + = 1'時,這就是'Counter'的尖叫聲。更何況這個問題是「我想數......」。 – lvc

+1

請注意,這隻有在每個列表中的元素的順序相同時纔有效,例如, 'Counter(chain.from_iterable([[1,2],[2,1]]))中x的組合(x,2)產生Counter({(1,2):1,(2,1) :1})'。如果要計算每個配對而不管順序如何,首先將每個列表轉換爲一個集合:Counter [([1,2])中的x的計數器(chain.from_iterable(combination(x,2)),set([ 1])])''產生'Counter({(1,2):2})'。 – Katrina