11

这似乎应该是一个显而易见的问题,但列表上的教程和文档不会出现。其中许多问题源于我的文本文件(数百 MB)的绝对大小以及我试图将它们归结为可由我的系统管理的东西。因此,我正在分段做我的工作,现在正在尝试合并结果。

我有多个词频列表(其中约 40 个)。这些列表既可以通过 Import[ ] 获取,也可以作为 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 >>, {"abattoir", 1}, {"abatement", 1}, {"abattagen", 1}, {"abatage", 1}, {"abated", 1}, {"abandonn", 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 >>, {"abatement", 1}, {"abattagen", 1}, {"abatage", 1}, {"abated", 1}, {"abandonn", 1}, {"abaiss", 1} , {"aback", 1}, {"aase", 1}, {"aaijaut", 1}, {"aaaah", 1}, {"aaa", 1}}

我想将它们组合起来,以便频率数据聚合:即,如果第二个文件有 30,419 次出现“the”并连接到第一个文件,它应该返回有 72,635 次出现(依此类推,因为我通过整个收藏)。

4

5 回答 5

10

听起来你需要GatherBy.

假设您的两个列表命名为data1and data2,然后使用

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

这很容易推广到任意数量的列表,而不仅仅是两个。

于 2011-10-24T13:57:40.990 回答
8

尝试使用哈希表,像这样。首先设置:

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

现在 egfreq["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
*)
于 2011-10-24T13:36:51.717 回答
8

这是一个直接Sow/Reap函数:

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

这是 acl 方法的简明形式:

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

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

  {#[[1, 1]], #2} & @@@ Most@DownValues@c
]

这似乎比我系统上的 Szabolcs 代码快一点:

data1 ~Join~ data2 ~GatherBy~ First /.
  {{{x_, a_}, {x_, b_}} :> {x, a + b}, {x : {_, _}} :> x}
于 2011-10-24T19:06:00.413 回答
6

有句老话,“如果你只有一把锤子,一切都会变成钉子。” 所以,这是我的锤子:SelectEquivalents

这可以使用以下方法更快地完成SelectEquivalents

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

按顺序,第一个参数显然只是连接列表,第二个参数是它们的分组依据(在这种情况下是第一个元素),第三个参数去掉字符串,只留下计数,第四个参数把它与字符串 as#1和列表中的计数一起返回 as #2

于 2011-10-24T14:52:03.513 回答
3

试试ReplaceRepeated

加入列表。然后使用

//. {{f1___, {a_, c1_}, f2___, {a_, c2_}, f3___} -> {f1, f2, f3, {a, c1 + c2}}}
于 2011-10-24T13:24:19.337 回答