sod*_*ate 7 python numpy multiprocessing python-2.7 python-click
我有一个庞大的列表,我需要处理,这需要一些时间,所以我把它分成4件,并用一些功能多处理每件.使用4个内核运行仍然需要一些时间,所以我想我会在函数中添加一些进度条,以便它可以告诉我处理列表时每个处理器的位置.
我的梦想是拥有这样的东西:
erasing close atoms, cpu0 [######..............................] 13%
erasing close atoms, cpu1 [#######.............................] 15%
erasing close atoms, cpu2 [######..............................] 13%
erasing close atoms, cpu3 [######..............................] 14%
Run Code Online (Sandbox Code Playgroud)
每个条随着函数循环的移动而移动.但相反,我得到一个持续的流程:
等等,填满我的终端窗口.
这是调用函数的主要python脚本:
from eraseCloseAtoms import *
from readPDB import *
import multiprocessing as mp
from vectorCalc import *
prot, cell = readPDB('file')
atoms = vectorCalc(cell)
output = mp.Queue()
# setup mp to erase grid atoms that are too close to the protein (dmin = 2.5A)
cpuNum = 4
tasks = len(atoms)
rangeSet = [tasks / cpuNum for i in range(cpuNum)]
for i in range(tasks % cpuNum):
rangeSet[i] += 1
rangeSet = np.array(rangeSet)
processes = []
for c in range(cpuNum):
na, nb = (int(np.sum(rangeSet[:c] + 1)), int(np.sum(rangeSet[:c + 1])))
processes.append(mp.Process(target=eraseCloseAtoms, args=(prot, atoms[na:nb], cell, 2.7, 2.5, output)))
for p in processes:
p.start()
results = [output.get() for p in processes]
for p in processes:
p.join()
atomsNew = results[0] + results[1] + results[2] + results[3]
Run Code Online (Sandbox Code Playgroud)
以下是功能eraseCloseAtoms():
import numpy as np
import click
def eraseCloseAtoms(protein, atoms, cell, spacing=2, dmin=1.4, output=None):
print 'just need to erase close atoms'
if dmin > spacing:
print 'the spacing needs to be larger than dmin'
return
grid = [int(cell[0] / spacing), int(cell[1] / spacing), int(cell[2] / spacing)]
selected = list(atoms)
with click.progressbar(length=len(atoms), label='erasing close atoms') as bar:
for i, atom in enumerate(atoms):
bar.update(i)
erased = False
coord = np.array(atom[6])
for ix in [-1, 0, 1]:
if erased:
break
for iy in [-1, 0, 1]:
if erased:
break
for iz in [-1, 0, 1]:
if erased:
break
for j in protein:
protCoord = np.array(protein[int(j)][6])
trueDist = getMinDist(protCoord, coord, cell, vectors)
if trueDist <= dmin:
selected.remove(atom)
erased = True
break
if output is None:
return selected
else:
output.put(selected)
Run Code Online (Sandbox Code Playgroud)
我在您的代码中看到两个问题。
第一个解释了为什么进度条经常显示100%而不是实际进度。当我认为您希望一步一步更新时,您正在呼叫bar.update(i)这会逐步提高小节的进度i。更好的方法是将Iterable传递给progressbar函数,并使其自动进行更新:
with click.progressbar(atoms, label='erasing close atoms') as bar:
for atom in bar:
erased = False
coord = np.array(atom[6])
# ...
Run Code Online (Sandbox Code Playgroud)
但是,由于您的代码存在第二个问题,它仍然无法同时用于多个迭代的流程,每个流程都有自己的进度条。该click.progressbar文档指出以下限制:
无需进行任何打印,否则进度条将被无意破坏。
这意味着只要您的进度条之一更新,它就会破坏所有其他活动进度条。
我认为没有简单的解决方案。交互式更新多行控制台输出非常困难(基本上,您需要使用curses或具有OS支持的类似“控制台GUI”库)。该click模块不具备该功能,它只能更新当前行。您最大的希望可能是扩展click.progressbar设计以在列中输出多个条,例如:
CPU1: [###### ] 52% CPU2: [### ] 30% CPU3: [######## ] 84%
Run Code Online (Sandbox Code Playgroud)
这将需要大量的代码来使其工作(特别是当更新来自多个进程时),但这并不是完全不切实际的。
接受的答案表示单击是不可能的,并且需要“数量不多的代码才能使它起作用”。
的确如此,还有另一个具有此功能的模块:tqdm https://github.com/tqdm/tqdm可以满足您的需求。
您可以在文档https://github.com/tqdm/tqdm#nested-progress-bars等中执行嵌套进度条。
| 归档时间: |
|
| 查看次数: |
3913 次 |
| 最近记录: |