2012-06-01 15 views
5

Aslında, "toplantı" hakkında bir veri kümem var. Örneğin, A, B, C'nin bir toplantısı var, ardından liste [A, B, C] olacaktır. Bunun gibi, her liste toplantıya katılan üyelerin listesini içerir. Bu yüzden:Python: Listeler listesindeki öğeler çiftlerinin sayma sıklığı

satırı1 = (A, B, C),

satırı2 = (A, C, D, E)

satırı3 = (D, F, G)

..

Her üye çiftinin bir araya geldiği sayıyı saymak istiyorum. Örneğin, üye A, satır1 ve satır2'den iki kez C ile buluşur ve B üyesi, satır1'den bir kere C ile karşılaşır. Yani,

A B C D E F G... 

A . 1 2 1 ... 

B 1 . 1 0 

C 

... İlk başta kolay olacağını düşündüm ama oldukça karıştı .. Böyle bir grafik yapmak istiyorum. Lütfen bana yardım edin ve şimdiden çok teşekkür ederim.

+1

Matrisleri nasıl katlayacağınızı öğrenmenin zamanı ... –

cevap

0

Bu, bir 2B dizi veya dict ile oldukça basit bir veri yapısı sorunudur. Çok fazla insanınız varsa diziler daha verimlidir, ama siz yapmadığınızı varsayacağım. Eğer büyük toplantıları ve daha verimli algoritmalar muhtemelen varsa bu gerçekten verimsiz olduğunu

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)] 

Not.

+1

Bir tuple -> int'ın daha mantıklı olacağını düşünüyorum - böylece "people_met [(person1, person2)]" aralarındaki toplantılardır. O zaman bir 'varsayılan' olması gerekmez - sadece başlangıçta itertools.combinations'dan doldurun. – lvc

+0

@lvc A 'defaultdict (int)', anlamsal olarak daha anlamlı hale getirir. Yeni bir kişi veri kümesine katılırsa, başka biriyle bir toplantıda kaç kez olduğunu sorup, bir "KeyError" yerine doğru cevabı - 0 - isteyebilirsiniz. Sıfırlarla başlatılması da oldukça Pythonic değildir. Asla bir "varsayılan" dizini eklemediniz, ancak daha iyi kod yazmanıza izin veriyor. – agf

+0

Düzenleme iyidir, ancak bu büyük veri kümeleri için hala yetersizdir, çünkü satırın kartezyen ürününü, yalnızca bileşimler yerine, kendiniz üretirsiniz. Python'un piller dahil olduğunu unutmayın - bunu yapmak için zaten bir yol var. – agf

0

Bu, matris ekleme ile çözebilmeniz gerektiği gibi görünüyor. Eğer toplam insan sayısını biliyorsanız (soruda G), cevabınız GxG matrisi olacaktır. LINE1 gelen kombinasyonlarla bir GXG matrisi oluşturun, ardından elle toplanmasıyla frekanslarda daha ziyade vb LINE2 gelen kombinasyonlarla bir GXG matris içinde

7

eklemek itertools birlikte collections.counter kullanın:

from collections import Counter 
from itertools import chain, combinations 

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

lines olduğu yerlerde yinelenen adlar yinelenebilir.

+0

+1. Orada her şey bir yerlerde. >: P –

+0

+1 bir çözüm için o kadar kör edici bir şekilde kendini gösterir ki, cevabınıza kadar fark etmediğim için kendimi tekmeliyorum.Diğer cevap 'defaultdict (int)' yi kullandığında ve 'd [item] + = 1' yaparsa,' Counter' için çığlık atıyor. “Saymak istiyorum…” sorusundan bahsetmiyorum. – lvc

+1

Not: Bu, yalnızca elemanların her listede aynı sırada olduğu takdirde çalışacaktır, örn. [Sayaç (chain.from_iterable (x (2, [)] [[1,2], [2,1]] x)] '' üretir 'Sayaç ({(1, 2): 1, (2, 1) : 1}). Sıralamadan bağımsız olarak her bir eşleştirmeyi saymak isterseniz, her listeyi bir ilk olarak ayarlayın: '[zincirleme (açık) (chain.from_iterable (x, 2) [set ([1,2]) 'de x için ayarlayın, [2, 1])])) 'Counter ({(1, 2): 2})' üretir. – Katrina

İlgili konular