2012-06-01 48 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