2011-10-24 23 views
11

Điều này có vẻ như nó phải là một câu hỏi rõ ràng, nhưng các hướng dẫn và tài liệu về danh sách không sắp tới. Nhiều người trong số những vấn đề này xuất phát từ kích thước tuyệt đối của các tập tin văn bản của tôi (hàng trăm MB) và nỗ lực của tôi để đun sôi chúng xuống một cái gì đó quản lý bởi hệ thống của tôi. Kết quả là, tôi đang làm công việc của mình trong phân đoạn và hiện đang cố gắng kết hợp các kết quả.Kết hợp danh sách dữ liệu tần số từ

Tôi có nhiều danh sách tần suất từ ​​(~ 40 trong số đó). Danh sách có thể được thực hiện thông qua Nhập [] hoặc dưới dạng biến được tạo trong Mathematica. Mỗi danh sách xuất hiện như sau và đã được tạo bằng cách sử dụng các lệnh Tally [] và Sort []:

{{"the", 42216}, {"of", 24903}, {"and", 18624 }, {"n", 16850}, {"trong",
16164}, {"de", 14930}, {"a", 14660}, {"đến", 14175}, {"la", 7347 }, {"là", 6030}, {"l", 5981}, {"le", 5735}, < < 51293 >>, {"abattoir", 1}, {"abattement", 1}, {"abattagen", 1}, {"abattage", 1}, {"bị bỏ qua", 1}, {"bỏ qua", 1}, {"abaiss", 1}, {"aback", 1}, {"aase", 1}, {"aaijaut", 1}, {"aaaah", 1}, {"aaa", 1}}

Dưới đây là một ví dụ về tập tin thứ hai:

{{ "the", 30.419}, { "n", 20.414}, { "de", 19.956}, { "của", 16.262} , {"và",
14488}, {"đến", 12726}, {"a", 12635}, {"trong", 11141}, {"la", 10739}, {"et", 9016 }, {"les", 8675}, {"le", 7748}, < < 101032 >>, {"abattement", 1}, {"abattagen", 1}, {"abattage", 1}, { "bị hủy", 1}, {"từ bỏ", 1}, {"abaiss", 1}, {"aback", 1}, {"aase", 1}, {"aaijaut", 1}, { "aaaah", 1}, {"aaa", 1}}

Tôi muốn kết hợp chúng để dữ liệu tần số tổng hợp: tức là nếu tệp thứ hai có 30.419 lần xuất hiện của 'the' và được nối với tệp thứ nhất, nó sẽ trả về rằng có 72.635 lần xuất hiện (và cứ như vậy khi tôi di chuyển thông qua toàn bộ bộ sưu tập).

+3

Câu hỏi liên quan chặt chẽ: http://stackoverflow.com/questions/5143575/aggregating-tally-counters –

+0

Cũng liên quan đến phần nào: http://stackoverflow.com/questions/7749633/time-efficient-partial-inverted -index-building/ –

Trả lời

10

Có vẻ như bạn cần GatherBy.

Giả sử hai danh sách của bạn được đặt tên data1data2, sau đó sử dụng

{#[[1, 1]], Total[#[[All, 2]]]} & /@ GatherBy[Join[data1, data2], First] 

này một cách dễ dàng khái quát đến bất kỳ số lượng các danh sách, không chỉ hai.

3

Hãy thử ReplaceRepeated.

Tham gia danh sách. Sau đó, sử dụng

//. {{f1___, {a_, c1_}, f2___, {a_, c2_}, f3___} -> {f1, f2, f3, {a, c1 + c2}}} 
+0

Tôi chắc chắn có những cách nhanh hơn. Trong bản chỉnh sửa của tôi, tôi đặt {a, c1 + c2} ở cuối đầu ra của quy tắc, để tiết kiệm một chút thời gian. – DavidC

+0

Mặc dù khái niệm thú vị, điều này rất chậm. –

8

Hãy thử sử dụng bảng băm như thế này. Trước tiên hãy thiết lập mọi thứ:

ClearAll[freq]; 
freq[_] = 0; 

Bây giờ, ví dụ: freq["safas"] trả về 0.Tiếp theo, nếu danh sách được định nghĩa là

lst1 = {{"the", 42216}, {"of", 24903}, {"and", 18624}, {"n", 
    16850}, {"in", 16164}, {"de", 14930}, {"a", 14660}, {"to", 
    14175}, {"la", 7347}, {"was", 6030}, {"l", 5981}, {"le", 
    5735}, {"abattoir", 1}, {"abattement", 1}, {"abattagen", 
    1}, {"abattage", 1}, {"abated", 1}, {"abandonn", 1}, {"abaiss", 
    1}, {"aback", 1}, {"aase", 1}, {"aaijaut", 1}, {"aaaah", 
    1}, {"aaa", 1}}; 
lst2 = {{"the", 30419}, {"n", 20414}, {"de", 19956}, {"of", 
    16262}, {"and", 14488}, {"to", 12726}, {"a", 12635}, {"in", 
    11141}, {"la", 10739}, {"et", 9016}, {"les", 8675}, {"le", 
    7748}, {"abattement", 1}, {"abattagen", 1}, {"abattage", 
    1}, {"abated", 1}, {"abandonn", 1}, {"abaiss", 1}, {"aback", 
    1}, {"aase", 1}, {"aaijaut", 1}, {"aaaah", 1}, {"aaa", 1}}; 

bạn có thể chạy này

Scan[(freq[#[[1]]] += #[[2]]) &, lst1] 

sau đó ví dụ như

freq["the"] 
(* 
42216 
*) 

và sau đó là danh sách tiếp theo

Scan[(freq[#[[1]]] += #[[2]]) &, lst2] 

sau đó ví dụ:

freq["the"] 
72635 

trong khi vẫn

freq["safas"] 
(* 
0 
*) 
+0

Điều này hoạt động thực sự nhanh chóng! Tuy nhiên, có cách nào để xuất danh sách lại với kết quả cuối cùng - tức là danh sách tổng hợp của tất cả các thuật ngữ (ví dụ: {{"the", 72635}, {"of", 41165} ...) [có thể là ở bất kỳ định dạng nào] –

+0

@ ian.milligan thử ví dụ: http: // stackoverflow này.com/questions/7165169/select-specific-symbol-definitions-in-mathematica-not-transformation-rules/7169185 # 7169185 – acl

6

Có một câu nói cũ, "nếu tất cả những gì bạn có là một cái búa, mọi thứ trở thành móng tay." Đây là búa của tôi: SelectEquivalents.

Điều này có thể được thực hiện nhanh hơn một chút bằng SelectEquivalents:

SelectEquivalents[data1~Join~data2, #[[1]]&, #[[2]]&, {#1, Total[#2]}&] 

Để, các param đầu tiên rõ ràng chỉ là danh sách tham gia, điều thứ hai là những gì họ đang nhóm lại theo (trong trường hợp này là người đầu tiên phần tử), chuỗi param thứ ba tắt chuỗi chỉ để lại số đếm và tham số thứ tư đặt nó trở lại cùng với chuỗi là #1 và số đếm trong danh sách là #2.

+0

@ ian.milligan, cũng xem [Biến thể của Faysal] (http://stackoverflow.com/questions)/4198961/what-is-in-your-mathematica-tool-bag/6245166 # 6245166) của 'SelectEquivalents'. Tôi, cá nhân, sẽ không làm cho mọi thứ trở thành 'Lựa chọn', nhưng biến thể của anh ấy cực kỳ linh hoạt. Và, cả hai phiên bản đều có khả năng chạy vòng quanh 'GatherBy'. – rcollyer

8

Đây là một trực tiếp Sow/Reap chức năng:

Reap[#2~Sow~# & @@@ data1~Join~data2;, _, {#, [email protected]#2} &][[2]] 

Dưới đây là một hình thức ngắn gọn của phương pháp acl của:

Module[{c}, 
    c[_] = 0; 

    c[#] += #2 & @@@ data1~Join~data2; 

    {#[[1, 1]], #2} & @@@ [email protected]@c 
] 

này dường như là nhanh hơn một chút Mã Szabolcs trên hệ thống của tôi:

data1 ~Join~ data2 ~GatherBy~ First /. 
    {{{x_, a_}, {x_, b_}} :> {x, a + b}, {x : {_, _}} :> x} 
+0

Ngoài ra, hình thức nhỏ gọn của phương pháp acl là đặc biệt thông minh. Tôi có một câu hỏi, mặc dù, trong việc thực hiện 'Reap', tại sao dấu chấm phẩy sau câu lệnh' Sow'? – rcollyer

+0

@ rcollyer đó là một câu hỏi hay. Đó là một thói quen cũ, nhưng có lẽ không phải là một thói quen tốt. Nó trực quan nhắc nhở tôi rằng tôi không sử dụng kết quả trực tiếp của biểu thức đó và tôi từng nghĩ rằng nó hiệu quả hơn, nhưng điều đó dường như không đúng. Nó có lợi thế là loại bỏ một đầu ra lớn, có thể rất chậm để định dạng ngay cả với màn hình Skeleton, nếu tôi quên '[[2]]' sau 'Reap'. Tôi nên xem xét sử dụng 'Quét' hoặc' Do' thay thế. –

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