给定来自 norvig.com/big.txt 的 big.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/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
我有一个奇怪的问题:我在rvm上安装了rubyonrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种
大家好!我想知道Ruby中未使用语法ClassName.method_name调用的方法是如何工作的。我头脑中的一些是puts、print、gets、chomp。可以在不使用点运算符的情况下调用这些方法。为什么是这样?他们来自哪里?我怎样才能看到这些方法的完整列表? 最佳答案 Kernel中的所有方法都可用于Object类的所有对象或从Object派生的任何类。您可以使用Kernel.instance_methods列出它们。 关于没有类的Ruby方法?,我们在StackOverflow
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。