【发布时间】:2013-04-02 09:09:00
【问题描述】:
Python 2.7.3
我有一个包含数千个数据文件的文件夹。每个数据文件都被提供给构造函数并进行大量处理。现在我正在遍历文件并按顺序处理它们:
class Foo:
def __init__(self,file):
self.bar = do_lots_of_stuff_with_numpy_and_scipy(file)
def do_lots_of_stuff_with_numpy_and_scipy(file):
pass
def get_foos(dir):
return [Foo(os.path.join(dir,file)) for file in os.listdir(dir)]
这很好用,但是太慢了。我想并行执行此操作。我试过了:
def parallel_get_foos(dir):
p = Pool()
foos = p.map(Foo, [os.path.join(dir,file) for file in os.listdir(dir)])
p.close()
p.join()
return foos
if __name__ == "__main__":
foos = parallel_get_foos(sys.argv[1])
但它只是有很多错误:
Process PoolWorker-7:
Traceback (most recent call last):
File "/l/python2.7/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/l/python2.7/lib/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "/l/python2.7/lib/python2.7/multiprocessing/pool.py", line 99, in worker
put((job, i, result))
File "/l/python2.7/lib/python2.7/multiprocessing/queues.py", line 390, in put
return send(obj)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
我尝试过创建一个函数来返回对象,例如:
def get_foo(file):
return Foo(file)
def parallel_get_foos(dir):
...
foos = p.map(get_foo, [os.path.join(dir,file) for file in os.listdir(dir)])
...
但正如预期的那样,我得到了同样的错误。
我已经阅读了大量类似的主题,试图解决类似这样的问题,但没有一个解决方案对我有帮助。所以我很感激任何帮助!
编辑:
Bakuriu 正确地推测我在我的 do_lots_of_stuff 方法中定义了一个非顶级函数。具体来说,我是这样做的:
def fit_curve(data,degree):
"""Fits a least-square polynomial function to the given data."""
sorted = data[data[:,0].argsort()].T
coefficients = numpy.polyfit(sorted[0],sorted[1],degree)
def eval(val,deg=degree):
res = 0
for coefficient in coefficients:
res += coefficient*val**deg
deg -= 1
return res
return eval
有没有办法让这个函数可以腌制?
【问题讨论】:
-
您使用
get_foo函数的方法实际上效果很好。此外,做p.map(Foo, [ ... ])工作。你唯一不能做的就是腌制一个特定的方法(比如__init__)。 -
不适合我 :( 顺便说一句,我使用的是 Python 2.7。
-
您能否展示一下
do_lots_of_stuff_with_numpy_and_scipy的组织方式或多或少?尤其是在哪里以及如何使用fit_curve函数?您不必写下所有细节,但要明确与该功能使用相关的主要控制流程,以便我们了解哪种替代方案可能适合您的情况。作为一个疯狂的猜测,你可以简单地拥有一个像def _eval(coefficients, val, degree):这样实现eval函数的函数,让fit_curve返回coefficients并将函数调用替换为_eval(coefs,val,degree)
标签: python parallel-processing multiprocessing pickle