Объединение списков данных частоты слова

Кажется, что это должен быть очевидный вопрос, но учебные пособия и документация по спискам не ожидаются. Многие из этих проблем связаны с огромными размерами моих текстовых файлов (сотни МБ) и мои попытки свести их к чему-то управляемому моей системой. В результате я делаю свою работу в сегментах, и теперь я пытаюсь совместить результаты.

У меня есть несколько списков частоты слов (~ 40 из них). Списки можно либо импортировать через [], либо как переменные, сгенерированные в Mathematica. Каждый список выглядит следующим образом и сгенерирован с использованием команд Tally [] и Sort []:

{{ "the", 42216}, { "of", 24903}, { "and", 18624}, { "n", 16850}, { "in",
16164}, { "de", 14930}, { "a", 14660}, { "to", 14175}, { "la", 7347} { "was", 6030}, { "l", 5981}, { "le", 5735}, < 51293 → , { "скотобойня" 1}, { "abattement", 1}, { "abattagen", 1}, { "abattage", 1}, { "abamed", 1}, { "restonn", 1}, { "abaiss", 1}, { "aback", 1}, { "aase", 1}, { "aaijaut", 1}, { "aaaah", 1}, { "aaa", 1}}

Вот пример второго файла:

{{ "the", 30419}, { "n", 20414}, { "de", 19956}, { "of", 16262}, { "and",
14488}, { "to", 12726}, { "a", 12635}, { "in", 11141}, { "la", 10739} { "et", 9016}, { "les", 8675}, { "le", 7748}, < 101032 → , { "abattement", 1}, { "abattagen", 1}, { "abattage", 1}, { "abamed", 1}, { "отказ", 1}, { "abaiss", 1}, { "aback", 1}, { "aase", 1}, { "aaijaut", 1}, { "aaaah", 1}, { "aaa", 1}}

Я хочу объединить их, чтобы агрегировать частотные данные: т.е. если второй файл имеет 30,419 вхождений "и" и присоединяется к первому файлу, он должен вернуть, что есть 72 635 случаев (и так далее, когда я перемещаюсь через всю коллекцию).

Ответ 1

Похоже, вам нужно GatherBy.

Предположим, что ваши два списка называются data1 и data2, затем используйте

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

Это легко обобщает на любое количество списков, а не только на два.

Ответ 2

Попробуйте использовать хеш-таблицу, например. Сначала задайте настройки:

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

Теперь, например, freq["safas"] возвращает 0. Далее, если списки определены как

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}};

вы можете запустить этот

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

после чего, например,

freq["the"]
(*
42216
*)

а затем следующий список

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

после чего, например,

freq["the"]
72635

пока еще

freq["safas"]
(*
0
*)

Ответ 3

Вот прямая функция Sow/Reap:

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

Вот краткая форма метода acl:

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

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

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

В моей системе это немного быстрее, чем код Szabolcs:

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

Ответ 4

Там старая поговорка: "Если у вас есть молот, все становится гвоздем". Итак, вот мой молот: SelectEquivalents.

Это можно сделать немного быстрее, используя SelectEquivalents:

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

В порядке, первый параметр - это, очевидно, только объединенные списки, второй - это то, что они сгруппированы (в этом случае первый элемент), третий параметр удаляет строку, оставляя только счет, а четвертый param помещает его вместе со строкой как #1 и подсчеты в списке как #2.

Ответ 5

Попробуйте ReplaceRepeated.

Присоединитесь к спискам. Затем используйте

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