Python用字典统计信息,python字典计数统计
索引引擎的基本工作原理是倒排索引,即一个文档中包含的文本依次映射到该文档;这个算法没有太多的猫腻。为了提高效率,可以将索引数据尽可能多地移入内存。
基本思想是举一个简单的例子。现在有以下文档(分词已经完成)及其包含的关键字:
doc_a:[word_w,word_x,word_y]
doc_b:
将它转换成
word_w-[doc_a]
word _ x-[文档_a,文档_b]
word_y-[doc_a,doc_c]
用Python代码写的Word_z-[doc_b]是
doc_a={id:a , words:[word_w , word_x , word_y]}
doc_b={id:b , words:[word_x , word_z]}
doc_c={id:c , words:[word_y]}
文档=[文档a,文档b,文档c]
indices=dict()
fordocindocs:
forwordindoc[words]:
ifwordnotinindices:
indexes[word]=[]
索引[单词]。追加(文档[id])
Printindices但是这里有个小技巧,就是判断当前单词是否已经在索引字典的分支中。
ifwordnotinindices:
indexes[word]=[]可以用dict的setdefault(key,default=None)接口代替。这个接口的作用是,如果键在字典里,那么就这么说,并得出相应的值;否则,创建一个新的键,并将默认的相应值设置为default。但是从设计的角度来看,我不明白为什么default会有一个缺省值None,这似乎没有太大的意义。如果你真的想使用这个接口,它通常会自带默认值,如下所示
fordocindocs:
forwordindoc[words]:
Indexes.setdefault (word,[])。追加(doc [id])。这就节省了分支,代码看起来也少了很多。
但是,在某些情况下,setdefault并不好用。当缺省值结构复杂,或者缺省值有副作用,以及后面会讨论的一种情况;总之,前两种情况是setdefault不适用于default,这需要惯性。
值的场景. 换言之, 为了兼顾这种需求, setdefault 可能会设计成
defsetdefault(self,key,default_factory):倘若真如此, 那么上面的代码应改成ifkeynotinself:
self[key]=default_factory()
returnself[key]
fordocindocs:不过实际上有其它替代方案, 这个最后会提到.forwordindoc['words']:
indices.setdefault(word,list).append(doc['id'])
如果说上面只是一个能预见但实际上可能根本不会遇到的 API 缺陷, 那么下面这个就略打脸了.
考虑现在要进行词频统计, 即一个词在文章中出现了多少次, 如果直接拿 dict 来写, 大致是
defword_count(words):当你兴致勃勃地跑起上面代码时, 代码会以迅雷不及掩脸之势把异常甩到你鼻尖上 --- 因为出现在 += 操作符左边的 count.setdefault(word, 0) 在 Python 中不是一个左值. 怎样, 现在开始念叨 C艹 类型体系的好了吧.count=dict()
forwordinwords:
count.setdefault(word,0)+=1
returncount
printword_count(['hiiragi','kagami','hiiragi','tukasa','yosimizu','kagami'])
因为 Python 把默认的字面常量 {} 等价于 dict() 就认为 dict 是银弹的思想是要不得的; Python 里面各种数据结构不少, 解决统计问题, 理想的方案是 collections.defaultdict 这个类. 下面的代码想必看一眼就明白
fromcollectionsimportdefaultdict完满解决了之前遇到的那些破事.
doc_a={'id':'a','words':['word_w','word_x','word_y']}
doc_b={'id':'b','words':['word_x','word_z']}
doc_c={'id':'c','words':['word_y']}
docs=[doc_a,doc_b,doc_c]
indices=defaultdict(list)
fordocindocs:
forwordindoc['words']:
indices[word].append(doc['id'])
printindices
defword_count(words):
count=defaultdict(int)
forwordinwords:
count[word]+=1
returncount
printword_count(['hiiragi','kagami','hiiragi','tukasa','yosimizu','kagami'])
此外 collections 里还有个 Counter , 可以粗略认为它是 defaultdict(int) 的扩展.
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。