【问题标题】:Multiprocessing with classes / Returning List - Python [closed]带类/返回列表的多处理 - Python [关闭]
【发布时间】:2014-01-25 01:18:44
【问题描述】:

我正在尝试并行化我为随机生成一些图像而制作的代码(针对我正在处理的特定问题)。当我使用类时,我发现多进程方法并不简单,我寻找了一些替代方案并找到了这种方法:

#https://gist.github.com/fiatmoney/1086393
#MultiprocessingMethods.py

def _pickle_method(method):
    func_name = method.im_func.__name__
    obj = method.im_self
    cls = method.im_class
    if func_name.startswith('__') and not func_name.endswith('__'): #deal with mangled names
        cls_name = cls.__name__.lstrip('_')
        func_name = '_' + cls_name + func_name
    return _unpickle_method, (func_name, obj, cls)


def _unpickle_method(func_name, obj, cls):
    for cls in cls.__mro__:
        try:
            func = cls.__dict__[func_name]
        except KeyError:
            pass
        else:
            break
    return func.__get__(obj, cls)

所以,我将它应用到我的代码中:

from multiprocessing import Pool
from PIL import Image

import MultiprocessingMethods as Mp
import Utils

import random
import pylab as plt  
import copy_reg
import types

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

class ImageData(object):

    def __init__(self, width, height, range_min=-1, range_max=1):
        self.width = width
        self.height = height
        #The values range each pixel can assume
        self.range_min = range_min
        self.range_max = range_max
        self.data = []
        for i in range(width):
            self.data.append([0] * height)

    def generate_heat_map_image(self, name):
        """
        Generate a heat map of the image
        :param name: the name of the file
        """
        #self.normalize_image_data()
        plt.figure()
        fig = plt.imshow(self.data, extent=[-1, 1, -1, 1])
        plt.colorbar(fig)
        plt.savefig(name+".png")
        plt.close()

    def shepard_interpolation(self, seeds=10):
        print type (self.data)
        #Code omitted 'cause it doesn't effect the problem 
        return self.data


if __name__ == '__main__':   
    x = [ImageData(50, 50), ImageData(50, 50)]
    p = Pool()
    outputs = p.map(ImageData.shepard_interpolation,x)

    #A [[[ ]]]
    print outputs
    for i in range(len(outputs)):
        # A [[ ]]
        print outputs[i]
        outputs[i].generate_heat_map_image("ImagesOutput/Entries/Entry"+str(i))   

现在我可以并行化我的过程,但我得到一个数组数组作为输出,我不知道为什么。在此之前,我总是得到一个 ImageData 数组,我可以生成一个热图图像 ma​​tplotlib。这种返回是否与多处理有关?我猜是这样,因为我得到“AttributeError:'list'对象没有属性'generate_heat_map_image'”,返回应该是ImageData类型的列表,也不是列表列表。我可以返回一个 ImageData 数组吗?

任何帮助将不胜感激。 提前致谢。

【问题讨论】:

    标签: python list class return multiprocessing


    【解决方案1】:

    解决了。我不得不说:

    def shepard_interpolation(self, seeds=10):
        print type (self.data)
        #Code omitted 'cause it doesn't effect the problem 
        return self
    

    连续 5 小时编程后发生的事情。 谢谢各位。

    【讨论】:

      【解决方案2】:

      ImageData 类标识错误,因此您的方法实际上并不属于该类,即使没有 multiprocessing ;这是正确的:

      class ImageData:
          def __init__(self, width, height, range_min=-1, range_max=1):
              self.width = width
              self.height = height
              #Which values each pixel can assume
              self.range_min = range_min
              self.range_max = range_max
              self.data = []
              for i in range(width):
                 self.data.append([0] * height)
      
          def interpolate_points(self, seeds):
              points = []
              f = []
              for i in range(seeds):
                  # Generate a cell position
                  pos_x = random.randrange(self.width)
                  pos_y = random.randrange(self.height)
      
                  # Save the f(x,y) data
                  x = Utils.translate_range(pos_x, 0, self.width, self.range_min, self.range_max)
                  y = Utils.translate_range(pos_y, 0, self.height, self.range_min, self.range_max)
                  z = Utils.function(x, y)
                  points.append([x, y])
      
                  f.append(z)
              for x in range(self.width):
                  xt = (Utils.translate_range(x, 0, self.width, self.range_min, self.range_max))
                  for y in range(self.height):
                      yt = (Utils.translate_range(y, 0, self.height, self.range_min, self.range_max))
                      self.data[x][y] = Utils.shepard_euclidian(points, f, [xt, yt], 3)
      
          # >>>> Note the identation change here!
          def generate_heat_map_image(self, name):
              """
              Generate a heat map of the image
              :param name: the name of the file
              """
      
              #self.normalize_image_data()
              plt.figure()
              fig = plt.imshow(self.data, extent=[-1, 1, -1, 1])
              plt.colorbar(fig)
              plt.savefig(name+".png")
              plt.close()
      

      【讨论】:

      • 我的代码中缩进没问题。当我粘贴它时,这是一个问题。我会编辑。
      • 你得到什么样的错误/异常?您可以发布堆栈跟踪吗?
      • 我发现用 Python 应用多处理并不简单。我找到了一个替代方案,但我仍然有问题。我会更新我的问题。谢谢你,@F.X.
      猜你喜欢
      • 2014-08-04
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-13
      • 2011-06-22
      相关资源
      最近更新 更多