Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在某一点上,在列表中看到二元图的次数_Python_Python 3.x_Text_N Gram - Fatal编程技术网

Python 在某一点上,在列表中看到二元图的次数

Python 在某一点上,在列表中看到二元图的次数,python,python-3.x,text,n-gram,Python,Python 3.x,Text,N Gram,假设我有这样一个文本: 'he is hdajs asdas da he is not asd as da s i am a da daas you am a' 我已根据本文创建了所有Bigram: >>> bigrams_ [('he', 'is'), ('is', 'hdajs'), ('hdajs', 'asdas'), ('asdas', 'da'), ('da', 'he'), ('he', 'is'), ('is', 'not'), ('not', 'asd'),

假设我有这样一个文本:

'he is hdajs asdas da he is not asd as da s i am a da daas you am a'
我已根据本文创建了所有Bigram:

>>> bigrams_
[('he', 'is'), ('is', 'hdajs'), ('hdajs', 'asdas'), ('asdas', 'da'), ('da', 'he'), ('he', 'is'), ('is', 'not'), ('not', 'asd'), ('asd', 'as'), ('as', 'da'), ('da', 's'), ('s', 'i'), ('i', 'am'), ('am', 'a'), ('a', 'da'), ('da', 'daas'), ('daas', 'you'), ('you', 'am'), ('am', 'a')]
现在我想创建一个新的bigram列表,其中每个bigram的第一个元素将是一个位置索引,显示在文本中某一点上,上面格式的某个bigram被看到了多少次,第二个元素将是初始列表中单词的bigram。例如,在上面的列表中,最后一个元素
('am','a')
已经出现了2次,因此在新的列表中它将对应于这个二元图:
(2,('am','a'))
。 这将是一种简洁的Python方式

您可以尝试以下方法:

s = 'he is hdajs asdas da he is not asd as da s i am a da daas you am a'
s1 = s.split()
new_data = list(set([(s.count(' '.join(b)), b) for b in [(s1[i], s1[i+1]) for i in range(len(s1)-1)]]))
输出:

[(2, ('am', 'a')), (1, ('da', 'daas')), (1, ('not', 'asd')), (1, ('s', 'i')), (1, ('da', 'he')), (1, ('you', 'am')), (2, ('he', 'is')), (1, ('is', 'not')), (1, ('asdas', 'da')), (1, ('asd', 'as')), (1, ('hdajs', 'asdas')), (1, ('a', 'da')), (1, ('daas', 'you')), (2, ('as', 'da')), (1, ('da', 's')), (1, ('is', 'hdajs')), (1, ('i', 'am'))]

您可以使用默认值为
count
对象的
defaultdict
,并逐步获取该键计数器的
next
值,例如:

from collections import defaultdict
from itertools import count

dd = defaultdict(lambda: count(1))
bigrams = [('he', 'is'), ('is', 'hdajs'), ('hdajs', 'asdas'), ('asdas', 'da'), ('da', 'he'), ('he', 'is'), ('is', 'not'), ('not', 'asd'), ('asd', 'as'), ('as', 'da'), ('da', 's'), ('s', 'i'), ('i', 'am'), ('am', 'a'), ('a', 'da'), ('da', 'daas'), ('daas', 'you'), ('you', 'am'), ('am', 'a')]
with_count = [(next(dd[bigram]), bigram) for bigram in bigrams]
给你:

[(1, ('he', 'is')),
 (1, ('is', 'hdajs')),
 (1, ('hdajs', 'asdas')),
 (1, ('asdas', 'da')),
 (1, ('da', 'he')),
 (2, ('he', 'is')),
 (1, ('is', 'not')),
 (1, ('not', 'asd')),
 (1, ('asd', 'as')),
 (1, ('as', 'da')),
 (1, ('da', 's')),
 (1, ('s', 'i')),
 (1, ('i', 'am')),
 (1, ('am', 'a')),
 (1, ('a', 'da')),
 (1, ('da', 'daas')),
 (1, ('daas', 'you')),
 (1, ('you', 'am')),
 (2, ('am', 'a'))]

我喜欢基于@JonClements itertools
count
的解决方案(+1),但我不认为
defaultdict
是必要的:

from itertools import count

text = 'he is hdajs asdas da he is not asd as da s i am a da daas you am a'

words = text.split()

bigrams = zip(words, words[1:])

seen = dict()

result = [(next(seen.setdefault(bigram, count(1))), bigram) for bigram in bigrams]

print(*result, sep='\n')
输出

(1, ('he', 'is'))
(1, ('is', 'hdajs'))
(1, ('hdajs', 'asdas'))
(1, ('asdas', 'da'))
(1, ('da', 'he'))
(2, ('he', 'is'))
(1, ('is', 'not'))
(1, ('not', 'asd'))
(1, ('asd', 'as'))
(1, ('as', 'da'))
(1, ('da', 's'))
(1, ('s', 'i'))
(1, ('i', 'am'))
(1, ('am', 'a'))
(1, ('a', 'da'))
(1, ('da', 'daas'))
(1, ('daas', 'you'))
(1, ('you', 'am'))
(2, ('am', 'a'))

“am”和“a”是如何被看到3次的?它只在你的文本中出现两次,除非我在这里遗漏了什么,你是对的。我道歉。我的意思是2次。除了它以前只被看到过一次,所以它应该是
(1,('am','a'))
-除非是累积计数,所有内容都以
1
开始?所有内容都以一开始。我不确定当我有一个嵌套的文本列表时,这是否是一个好的解决方案。例如,假设我有一个文本<代码>[“我是我是你是他是”,“你是他是我是”,“我是你是”],其中每个句子都是一个单独的文档。我希望在启动新字符串时重置索引。如果我写
[[(next(indexer[elem]),elem)for elem in bigram]for bigram in bigram]
,它将继续计算并递增bigram索引,而不会在每个新文档开始时重置。最终列表中的最后一个('i','am')将获得4的索引,但它在最后一个文档中出现过一次。是的
.clear()
在适当的地方打开计数器,或为特定子部分创建新计数器…谢谢。所以用列表理解来写可能不是一个好主意。好吧,你可以把它全部编成一个列表,但是可读性不是很好。无论是清除同一个索引器还是创建一个新索引器,都是最简单的方法。。。