2012-06-01 72 views
5

Thực ra, tôi có tập dữ liệu về "cuộc họp". Ví dụ, A, B, C có một cuộc họp, sau đó danh sách sẽ là [A, B, C]. Như thế này, mỗi danh sách sẽ chứa một danh sách các thành viên tham gia cuộc họp. Do đó:Python: Đếm tần số của các phần tử trong danh sách các danh sách

line1 = (A, B, C)

dòng2 = (A, C, D, E)

Line3 = (D, F, G)

..

Tôi chỉ muốn đếm số lần mỗi cặp thành viên gặp nhau. Ví dụ, thành viên A gặp C hai lần từ line1 và line2 và thành viên B gặp C một lần từ dòng1. Vì vậy, tôi muốn thực hiện một biểu đồ như thế này ..

A B C D E F G... 

A . 1 2 1 ... 

B 1 . 1 0 

C 

...

Tôi nghĩ rằng nó sẽ được dễ dàng ở người đầu tiên nhưng tôi khá bối rối. Xin hãy giúp tôi và cảm ơn bạn rất nhiều trước.

+1

Thời gian để tìm hiểu cách nhân ma trận ... –

Trả lời

0

Đây là vấn đề cấu trúc dữ liệu khá đơn giản với mảng 2D hoặc dict. Mảng hiệu quả hơn nếu bạn có nhiều người, nhưng tôi sẽ giả sử bạn không làm như vậy.

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

Lưu ý rằng điều này thực sự không hiệu quả nếu bạn có các cuộc họp lớn và các thuật toán hiệu quả hơn có thể tồn tại.

+1

Tôi nghĩ rằng một mệnh đề của tuple -> int sẽ có ý nghĩa hơn - để 'people_met [(person1, person2)]' là các cuộc họp giữa chúng. Sau đó, nó không cần phải là một 'defaultdict' - chỉ cần điền nó ban đầu từ' itertools.combinations'. – lvc

+0

@lvc Một 'defaultdict (int)' có ý nghĩa hơn về mặt ngữ nghĩa. Nếu một người mới tham gia tập dữ liệu, bạn có thể yêu cầu bao nhiêu lần anh ta tham gia một cuộc họp với bất kỳ ai khác và nhận được câu trả lời đúng - 0 - thay vì một 'KeyError'. Ngoài ra khởi tạo với số không là khá un-Pythonic. Bạn không bao giờ _need_ một 'defaultdict' nhưng nó cho phép bạn viết mã tốt hơn. – agf

+0

Chỉnh sửa là tốt, nhưng điều này vẫn không hiệu quả đối với các tập dữ liệu lớn bởi vì bạn tạo ra sản phẩm Descartes của dòng với chính nó, thay vì chỉ các kết hợp. Hãy nhớ rằng Python là pin được bao gồm - đã có một cách để làm điều đó. – agf

0

Có vẻ như bạn sẽ có thể giải quyết vấn đề này với việc bổ sung ma trận. Nếu bạn biết tổng số người (G trong câu hỏi), thì câu trả lời của bạn sẽ là ma trận GxG. Tạo một ma trận với các kết hợp từ line1 GxG, sau đó thêm vào một ma trận với các kết hợp từ dòng2 GxG vv

7

Thay vì tần số bằng tay tổng hợp, sử dụng collections.counter cùng với itertools:

from collections import Counter 
from itertools import chain, combinations 

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

đâu lines là một iterable của iterables của tên.

+0

+1 để sử dụng thư viện Python. Mọi thứ ở trong đó đâu đó. >: P –

+0

+1 cho một giải pháp để tự rõ ràng là tôi tự đá mình vì không nhận thấy nó cho đến khi câu trả lời của bạn.Khi câu trả lời khác sử dụng 'defaultdict (int)' và làm 'd [item] + = 1' rất nhiều, đó là loại hét lên cho một' Counter'. Chưa kể câu hỏi là "Tôi muốn đếm ...". – lvc

+1

Lưu ý rằng điều này sẽ chỉ hoạt động nếu các phần tử nằm trong cùng một thứ tự trong mọi danh sách, ví dụ: 'Counter (chain.from_iterable (các kết hợp (x, 2) cho x trong [[1,2], [2,1]]))' tạo 'Số đếm ({(1, 2): 1, (2, 1) : 1}) '. Nếu bạn muốn đếm từng cặp bất kể thứ tự, hãy chuyển từng danh sách thành một tập hợp đầu tiên: 'Counter (chain.from_iterable (kết hợp (x, 2) cho x trong [set ([1,2]), set ([2, 1])])) 'tạo' Số đếm ({(1, 2): 2}) '. – Katrina

Các vấn đề liên quan