gpt4 book ai didi

python - 真正快速地计算双字母组(有或没有多处理) - python

转载 作者:太空狗 更新时间:2023-10-29 21:10:44 25 4
gpt4 key购买 nike

给定来自 norvig.com/big.txtbig.txt ,目标是真正快速地计算双字母组(想象一下,我必须重复此计数 100,000 次)。

根据 Fast/Optimize N-gram implementations in python , 像这样提取二元组是最佳的:

_bigrams = zip(*[text[i:] for i in range(2)])

如果我使用的是 Python3,生成器将不会被评估,直到我使用 list(_bigrams) 或其他一些执行相同操作的函数实现它.

import io
from collections import Counter

import time
with io.open('big.txt', 'r', encoding='utf8') as fin:
text = fin.read().lower().replace(u' ', u"\uE000")

while True:
_bigrams = zip(*[text[i:] for i in range(2)])
start = time.time()
top100 = Counter(_bigrams).most_common(100)
# Do some manipulation to text and repeat the counting.
text = manipulate(text, top100)

但是每次迭代需要大约 1 秒以上的时间,而 100,000 次迭代就太长了。

我也尝试过 sklearn CountVectorizer,但提取、计数和获取前 100 个二元语法的时间与原生 python 相当。

然后我尝试了一些多处理,使用来自 Python multiprocessing and a shared counter 的轻微修改和 http://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessing :

from multiprocessing import Process, Manager, Lock

import time

class MultiProcCounter(object):
def __init__(self):
self.dictionary = Manager().dict()
self.lock = Lock()

def increment(self, item):
with self.lock:
self.dictionary[item] = self.dictionary.get(item, 0) + 1

def func(counter, item):
counter.increment(item)

def multiproc_count(inputs):
counter = MultiProcCounter()
procs = [Process(target=func, args=(counter,_in)) for _in in inputs]
for p in procs: p.start()
for p in procs: p.join()
return counter.dictionary

inputs = [1,1,1,1,2,2,3,4,4,5,2,2,3,1,2]

print (multiproc_count(inputs))

但是在二元组计数中使用 MultiProcCounter 每次迭代花费的时间甚至超过 1+ 秒。我不知道为什么会这样,使用 int 示例的虚拟列表,multiproc_count 工作得很好。

我试过:

import io
from collections import Counter

import time
with io.open('big.txt', 'r', encoding='utf8') as fin:
text = fin.read().lower().replace(u' ', u"\uE000")

while True:
_bigrams = zip(*[text[i:] for i in range(2)])
start = time.time()
top100 = Counter(multiproc_count(_bigrams)).most_common(100)

有什么方法可以在 Python 中真正快速地计算二元语法吗?

最佳答案

import os, thread

text = 'I really like cheese' #just load whatever you want here, this is just an example

CORE_NUMBER = os.cpu_count() # may not be available, just replace with how many cores you have if it crashes

ready = []
bigrams = []

def extract_bigrams(cores):
global ready, bigrams
bigrams = []
ready = []
for a in xrange(cores): #xrange is best for performance
bigrams.append(0)
ready.append(0)
cpnt = 0#current point
iterator = int(len(text)/cores)
for a in xrange(cores-1):
thread.start_new(extract_bigrams2, (cpnt, cpnt+iterator+1, a)) #overlap is intentional
cpnt += iterator
thread.start_new(extract_bigrams2, (cpnt, len(text), a+1))
while 0 in ready:
pass

def extract_bigrams2(startpoint, endpoint, threadnum):
global ready, bigrams
ready[threadnum] = 0
bigrams[threadnum] = zip(*[text[startpoint+i:endpoint] for i in xrange(2)])
ready[threadnum] = 1

extract_bigrams(CORE_NUMBER)
thebigrams = []
for a in bigrams:
thebigrams+=a

print thebigrams

这个程序有一些问题,比如它没有过滤掉空格或标点符号,但我制作这个程序是为了展示你应该拍摄的内容。您可以轻松地对其进行编辑以满足您的需要。

该程序会自动检测您的计算机有多少个内核,并创建该数量的线程,试图平均分配它寻找二元组的区域。我只能在学校拥有的计算机上的在线浏览器中测试这段代码,所以我不能确定它是否完全有效。如果有任何问题或疑问,请在评论中留下。

关于python - 真正快速地计算双字母组(有或没有多处理) - python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40373414/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com