pro*_*ian 5 text wolfram-mathematica
在对列表操作的文档/过去问题进行管道调查后,我发现空白 - 许多案例涉及数字,而我正在处理大量文本.
我有一个常见的三字短语(三字母)的排序列表,它出现在大量的文本信息中,通过Mathematica的Partition [],Tally []和Sort []命令生成.我正在操作的数据类型的一个示例(我有数百个这样的文件):
{{{wa,wa,wa},66},{{i,love,you},62},{{la,la,la},50},{{meaning,of,life},42},{ on,come,on},40},{{come,on,come},40},{{是的,是的,是的},38},{{不,不,不是},36},{{我们, re,gonna},36},{{you,love,me},35},{{in,love,with},32},{{the,way,you},30},{{i,want,and to},30},{{back,to,me},29},<< 38211 >>,{{of,an,xke},1}}
我希望搜索这个文件,这样如果输入是"意义,生命",它将返回"42".我觉得我必须忽略一些明显的东西,但在修补过后我在这里碰了一堵砖墙.Mathematica在其文档中数量很多,这是......好吧,不足为奇.
假设您可以以您概述的形式将数据加载到Mathematica中,一个非常简单的事情是创建一个哈希表,其中三元组将是(复合)键.这是你的样本(你给出的部分):
trigrams = {{{"wa", "wa", "wa"}, 66}, {{"i", "love", "you"}, 62},
{{"la", "la", "la"}, 50}, {{"meaning", "of", "life"}, 42},
{{"on", "come", "on"}, 40}, {{"come", "on", "come"}, 40},
{{"yeah", "yeah", "yeah"}, 38}, {{"no", "no", "no"}, 36},
{{"we", "re", "gonna"}, 36}, {{"you", "love", "me"}, 35},
{{"in", "love", "with"}, 32}, {{"the", "way", "you"}, 30},
{{"i", "want", "to"}, 30}, {{"back", "to", "me"}, 29},
{{"of", "an", "xke"}, 1}};
Run Code Online (Sandbox Code Playgroud)
以下是创建哈希表的一种可能方法:
Clear[trigramHash];
(trigramHash[Sequence @@ #1] = #2) & @@@ trigrams;
Run Code Online (Sandbox Code Playgroud)
现在,我们使用它
In[16]:= trigramHash["meaning","of","life"]
Out[16]= 42
Run Code Online (Sandbox Code Playgroud)
当然,如果您执行许多搜索,这种方法将是有益的.
编辑
如果你有很多文件并希望在Mathematica中有效地搜索它们,你可以做的一件事是使用上面的散列机制将你的所有文件转换为.mx二进制Mathematica文件.这些文件针对快速加载进行了优化,并作为要存储的定义的持久性机制.以下是它的工作原理:
In[20]:= DumpSave["C:\\Temp\\trigrams.mx",trigramHash]
Out[20]= {trigramHash}
In[21]:= Quit[]
In[1]:= Get["C:\\Temp\\trigrams.mx"]
In[2]:= trigramHash["meaning","of","life"]
Out[2]= 42
Run Code Online (Sandbox Code Playgroud)
您DumpSave用来创建一个.mx文件.因此,建议的过程是将数据加载到Mathematica,逐个文件,创建哈希(您可以使用SubValues索引特定哈希表索引文件的索引),然后将这些定义保存到.mx文件中.通过这种方式,您可以快速加载和快速搜索,并且您可以自由决定在任何给定时间将数据的哪一部分保存到Mathematica中(几乎没有性能损失,通常与文件加载相关).
这可能没有Leonid给出的解决方案那么快,但你可以将你的对列表变成一个规则列表.
In[1]:= trigrams = {{{"wa", "wa", "wa"}, 66}, {{"i", "love", "you"},
62}, {{"la", "la", "la"}, 50}, {{"meaning", "of", "life"},
42}, {{"on", "come", "on"}, 40}, {{"come", "on", "come"},
40}, {{"yeah", "yeah", "yeah"}, 38}, {{"no", "no", "no"},
36}, {{"we", "re", "gonna"}, 36}, {{"you", "love", "me"},
35}, {{"in", "love", "with"}, 32}, {{"the", "way", "you"},
30}, {{"i", "want", "to"}, 30}, {{"back", "to", "me"},
29}, {{"of", "an", "xke"}, 1}};
In[2]:= trigramRules = Rule @@@ trigrams;
Run Code Online (Sandbox Code Playgroud)
哪个(如果你愿意)你可以包含一个与Leonid有类似行为的函数
In[3]:= trigram[seq__String] := {seq} /. trigramRules
In[4]:= trigram["meaning", "of", "life"]
Out[4]= 42
Run Code Online (Sandbox Code Playgroud)
由于您有一个非常大的对列表,因此可以通过使用来加速生成的规则的应用Dispatch.也就是说,除了定义trigramRules使用外,其他所有内容都与上面相同
trigramRules = Dispatch[Rule @@@ trigrams]
Run Code Online (Sandbox Code Playgroud)
这是将字符串中的单个单词放入列表的一种方法.
In[262]:= str = "meaning, of, life"; ReadList[
StringToStream[str], Word, WordSeparators -> {",", " "}]
Out[262]= {"meaning", "of", "life"}
Run Code Online (Sandbox Code Playgroud)
您可以在案例或其他形式的查找中使用它来获得42结果(非常可疑,那个数字......)
---编辑---
通过"查找",我想到了Leonid Shifrin所展示的那种机制.我不确定遇到的困难是,或者只是从字符串转换为三元组列表.我(仅)展示了管理后者的方法.
---结束编辑---
---编辑2 ---
评论显示了避免ReadList的方法.让我说明我欣喜若狂,我设法找到了这种方法.下面是我在原始响应中输入的代码,然后在我意识到有更简洁的代码时被替换.
str = "meaning, of, life";
commaposns = StringPosition[str, ", "];
substrposns =
Partition[
Join[{1},
Riffle[commaposns[[All, 1]] - 1, commaposns[[All, 2]] + 1], {-1}],
2];
substrs = Map[StringTake[str, #] &, substrposns]
Out[259]= {"meaning", "of", "life"}
Run Code Online (Sandbox Code Playgroud)
底线(几乎字面意义):我可以找到其他人的复杂方法,并且比大多数人更好.
---结束编辑---
Daniel Lichtblau