并行化距离计算方法与多处理

时间:2015-07-11 10:49:39

标签: python python-2.7 distance python-multiprocessing

这个问题与我几天前发布的other one有关;我已阅读this question有关使用实例方法进行multiprocessing酸洗的问题。问题是我不明白如何应用提供给我案例的解决方案:

def _pickle_method(method):
    # Author: Steven Bethard
    # http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods
    func_name = method.im_func.__name__
    obj = method.im_self
    cls = method.im_class
    cls_name = ''
    if func_name.startswith('__') and not func_name.endswith('__'):
        cls_name = cls.__name__.lstrip('_')
    if cls_name:
        func_name = '_' + cls_name + func_name
    return _unpickle_method, (func_name, obj, cls)

def _unpickle_method(func_name, obj, cls):
    # Author: Steven Bethard
    # http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods
    for cls in cls.mro():
        try:
            func = cls.__dict__[func_name]
        except KeyError:
            pass
        else:
            break
    return func.__get__(obj, cls)

copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)

class Circle(Feature):
# Stuff...
    def __points_distance(self,points):
        xa = n.array([self.xc,self.yc]).reshape((1,2))
        d = n.abs(dist.cdist(points,xa) - self.radius)
        return d

def points_distance(self,points,pool=None):
    if pool:
        return pool.map(self.__points_distance,points)
    else:
        return self.__points_distance(points)

运行此操作时出现ValueError: XA must be a 2-dimensional array错误:

import tra.features as fts
import numpy as np
import multiprocessing as mp

points = np.random.random(size=(1000,2))
circle_points = np.random.random(size=(3,2))

feature = fts.Circle(circle_points)

pool = mp.Pool()
ds = feature.points_distance(points,pool=pool)

但它(显然)在执行时起作用:

pool = None
ds = feature.points_distance(points,pool=pool)

任何线索?

这与this(我检查this实现)不同,因为该方法在另一个实例化Circle类并调用其points_distance方法的类中使用。在任何情况下,另一个区别是points_distance方法使用期望(n,2)形scipy.spatial.distance.cdist的{​​{1}}。它在使用串行版本时有效,但在并行使用时会引发我提到的异常。我想有一个关于cPickle传递的论点的警告。

3 个答案:

答案 0 :(得分:3)

我认为这里存在很多混淆,所以我不确定我是否理解这个问题。

例外NameError: global name 'pool' is not defined不是由于腌制问题,而是由于范围问题。

该方法在其范围内找不到pool。尝试通过将pool引用传递给方法来修复它。

其他事情:

pool = mp.Pool(mp.cpu_count())

cpu_count()调用是多余的,因为池已经产生了与默认情况下CPU相同数量的工作程序。

答案 1 :(得分:1)

传递给points的{​​{1}}数组的形状为(1000,2)。当pool.map拆分为pool.map参数传递给points时, 数组只有形状(2,)。

在致电__points_distance之前,尝试将points.shape = (1, 2)添加到__points_distance的正文中。

答案 2 :(得分:0)

pool变量是在Circle类之外定义的,所以points_distance() will be unable to find pool`在其命名空间中:

向Circle或Feature添加一个接受pool的构造函数,并将要使用的池传递给RansacFeature,我假设您为Circle实例化{{1}}。