Python 3.x 听写/列表理解在文本tada上的表现
我必须处理一个包含4000个字符串的列表,其中每个字符串代表一个文档。我的目标是计算每个单词出现的文档数,并返回一个dict,如: {单词:出现的文档数} 我写了两种不同的方法,它们适用于一小部分文档。一个使用基本的迭代和条件,另一个使用理解和一些功能特性,如lambda和map。以下是两个版本: 方法1Python 3.x 听写/列表理解在文本tada上的表现,python-3.x,performance,functional-programming,Python 3.x,Performance,Functional Programming,我必须处理一个包含4000个字符串的列表,其中每个字符串代表一个文档。我的目标是计算每个单词出现的文档数,并返回一个dict,如: {单词:出现的文档数} 我写了两种不同的方法,它们适用于一小部分文档。一个使用基本的迭代和条件,另一个使用理解和一些功能特性,如lambda和map。以下是两个版本: 方法1 def corpus_word_frequency(corpus_text): bag_of_words = " ".join(corpus_text).split() to
def corpus_word_frequency(corpus_text):
bag_of_words = " ".join(corpus_text).split()
tokens = set(bag_of_words)
words_frequency = {}
for doc in corpus_text:
text = doc.split()
for word in tokens:
if word in text:
if word in words_frequency.keys():
words_frequency[word] += 1
else:
words_frequency[word] = 1
return words_frequency
方法2
def corpus_word_frequency(corpus_text):
"""docstring"""
bag_of_words = " ".join(corpus_text).split()
tokens = set(bag_of_words)
return {
token: sum(
map(lambda doc: 1 if token in doc.split() else 0, corpus_text))
for token in tokens
}
问题是:方法1对我来说很慢,但它是可行的,但是方法2我不能忍受等待它结束,它太多了。那么,列表理解性能是问题所在吗?地图和lambda的使用?还有别的吗?有没有办法使方法2更有效?使用示例文件,我将您的函数与内置的集合进行了比较。Counter
:
In [1]: from collections import Counter
In [2]: def method1(corpus_text):
...: bag_of_words = " ".join(corpus_text).split()
...: tokens = set(bag_of_words)
...: words_frequency = {}
...: for doc in corpus_text:
...: text = doc.split()
...: for word in tokens:
...: if word in text:
...: if word in words_frequency.keys():
...: words_frequency[word] += 1
...: else:
...: words_frequency[word] = 1
...: return words_frequency
In [3]: def method2(corpus_text):
...: bag_of_words = " ".join(corpus_text).split()
...: tokens = set(bag_of_words)
...: return {
...: token: sum(
...: map(lambda doc: 1 if token in doc.split() else 0, corpus_text))
...: for token in tokens
...: }
In [4]: with open("Latin-Lipsum.txt") as file:
...: text = file.read()
In [5]: method1(text)
Out[5]:
{'L': 1,
'o': 63,
'r': 72,
...
'O': 1,
'P': 1,
'j': 1}
In [6]: Counter(text)
Out[6]:
Counter({'L': 1,
'o': 63,
'r': 72,
...
'O': 1,
'P': 1,
'j': 1})
它们的执行几乎完全相同,只是在本例中,计数器也对\n
字符进行计数
就速度而言,计数器
要快得多:
In [7]: %timeit method1(text)
1.96 ms ± 32.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [8]: %timeit method2(text)
10.5 ms ± 19.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [9]: %timeit Counter(text)
43.8 µs ± 50.4 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
您的第二种方法确实比第一种方法慢,而且计数器
比这两种方法快得多。使用示例文件,我将您的函数与内置的集合进行了比较。计数器
:
In [1]: from collections import Counter
In [2]: def method1(corpus_text):
...: bag_of_words = " ".join(corpus_text).split()
...: tokens = set(bag_of_words)
...: words_frequency = {}
...: for doc in corpus_text:
...: text = doc.split()
...: for word in tokens:
...: if word in text:
...: if word in words_frequency.keys():
...: words_frequency[word] += 1
...: else:
...: words_frequency[word] = 1
...: return words_frequency
In [3]: def method2(corpus_text):
...: bag_of_words = " ".join(corpus_text).split()
...: tokens = set(bag_of_words)
...: return {
...: token: sum(
...: map(lambda doc: 1 if token in doc.split() else 0, corpus_text))
...: for token in tokens
...: }
In [4]: with open("Latin-Lipsum.txt") as file:
...: text = file.read()
In [5]: method1(text)
Out[5]:
{'L': 1,
'o': 63,
'r': 72,
...
'O': 1,
'P': 1,
'j': 1}
In [6]: Counter(text)
Out[6]:
Counter({'L': 1,
'o': 63,
'r': 72,
...
'O': 1,
'P': 1,
'j': 1})
它们的执行几乎完全相同,只是在本例中,计数器也对\n
字符进行计数
就速度而言,计数器
要快得多:
In [7]: %timeit method1(text)
1.96 ms ± 32.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [8]: %timeit method2(text)
10.5 ms ± 19.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [9]: %timeit Counter(text)
43.8 µs ± 50.4 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
您的第二种方法确实比第一种方法慢,而且计数器
比这两种方法快得多。您看过内置的吗?除此之外,lambda
与Python中的其他方法相比通常非常慢。我第一次看到如何解决我的问题时遇到了collections.Counter,但在另一次讨论中看到它有点慢,所以我尝试先实现一些东西。如果这两种方法都没有解决方案,这是我的下一个选择。你看过内置的了吗?除此之外,lambda
与Python中的其他方法相比通常非常慢。我第一次看到如何解决我的问题时遇到了collections.Counter,但在另一次讨论中看到它有点慢,所以我尝试先实现一些东西。这是我的下一个选择,以防这两种方法缺乏解决方案。