2010-02-17 154 views
2

对不起,我将尽可能具体。在python中合并词典

我正在研究文本挖掘应用程序。我有大量的键值对的形式((字,语料库) - > occurence_count)(一切都是一个整数),我存储在多个Python字典(元组 - >诠释)。这些值分布在磁盘上的多个文件中(我对它们进行了腌制)。为了理解数据,我需要汇总这些字典基本上,我需要找出一种方法来查找所有字典中某个特定键的所有出现,并将它们相加以获得总数。

如果我同时加载多个词典,我耗尽内存,这是我给他们摆在首位分裂的原因。当我尝试时,我遇到了性能问题。我目前正在尝试将值存储在数据库(mysql)中,一次处理多个字典,因为mysql提供了行级锁定,这两者都很好(因为这意味着我可以并行化该操作),而且不好(因为它会减慢插入查询)

我在这里有什么选择?编写部分磁盘的字典是否是一个好主意,这样我就可以一次处理一个字典?用LRU替换策略?有什么我完全无视的东西吗?

谢谢!

+0

定义“大数”。 “我用完了内存”。真?没有像词典中的元素数量这样的细节,我觉得这很难理解。 “当我尝试时,我遇到了性能问题”。试过什么? –

+0

当你说“一切都是整数”时,你的意思是说单词和语料库是单词和语料库的整数ID?单词id在各个语料库中是否一致? – forefinger

+0

谢谢大家!我重新定义了一些问题来解决它。 – fsm

回答

0

这样的事情,如果我明白你的问题正确

from collections import defaultdict 
import pickle 

result = defaultdict(int) 
for fn in filenames: 
    data_dict = pickle.load(open(fn)) 
    for k,count in data_dict.items(): 
     word,corpus = k 
     result[k]+=count 
2

基于磁盘的字典般的存在 - 看看shelve模块。进入货架的密钥必须是字符串,但是您可以简单地在元组上使用str以获得等效的字符串键;再加上,我读了您的问与答的理解是,你只想要word为重点,所以这是更容易(无论是str - 或者,词汇< 4GB,一个struct.pack - 将被罚款)。

一个好的关系引擎(尤其是PostgreSQL)可以很好地为您服务,但是每次处理一个字典以将所有语料库中的每个单词出现聚合到一个shelf对象中也应该是OK(不是很快,但是更简单,因为shelf是如此的相似,dict除了上的按键[类型约束和可变值的警告,但由于你的价值观是int s表示不用关心你)。

0
  1. 如果我理解正确你的问题,你有话和语料库整数ID,那么你可以从字典切换到列表获得一些性能提升,甚至更好,一个numpy的阵列。这可能很烦人!

    基本上,你需要一个整数,我们可以调用newid的更换元组。你希望所有的新手都能对应一个单词,语料库对,所以我要把每个语料库中的单词都计算在内,然后对每个语料库都有一个开始的新单词。 (词,语料库)的新词将是词+ start_newid [语料库]。

    如果我误解你,你没有这样的id,那么我认为这个建议可能仍然是有用的,但你必须处理您的数据,让它进入整数格式的元组。

  2. 你可以尝试的另一件事是rechunking数据。

    假设你只能在内存中保存这些怪物中的1.1个。然后,您可以加载一个,然后创建一个较小的词典或数组,它只对应于(词,语料库)对的前10%。您可以扫描加载的字典,并处理前10%中的任何一个。完成后,您可以将结果写回到磁盘,并在第二个10%时再次进行传递。这将需要10次传球,但这可能对你很好。

    如果你根据内存中的内容选择了以前的分块,那么你将不得不任意分割你的旧分类,这样你可以在内存中保存一个分类,同时还可以保存结果字典/数组。