2015-10-30 22 views
1

我有一个python脚本,可以从列表中计算矩阵的特征值,我想按照原始矩阵的顺序将这些特征值插入到另一个集合中,喜欢通过产生多个进程来做到这一点。序列化迭代器对象在Python中的进程之间传递

这里是我的代码:

import time 
import collections 
import numpy as NP 
from scipy import linalg as LA 

from joblib import Parallel, delayed 

def computeEigenV(unit_of_work): 
    current_index = unit_of_work[0] 
    current_matrix = unit_of_work[1] 

    e_vals, e_vecs = LA.eig(current_matrix) 
    finished_unit = (current_index, lowEV[::-1]) 
    return finished_unit 

def run(work_list): 
    pool = Parallel(n_jobs = -1, verbose = 1, pre_dispatch = 'all') 
    results = pool(delayed(computeEigenV)(unit_of_work) for unit_of_work in work_list) 
return results 

if __name__ == '__main__': 
    # create original array of matrices 
    original_matrix_list = [] 
    work_list = [] 

    #basic set up so we can run this test 
    for i in range(0, 100): 
     # generate the matrix & unit or work 
     matrix = NP.random.random_integers(0, 100, (500, 500)) 
     #insert into respective resources 
     original_matrix_list.append(matrix) 

    for i, matrix in enumerate(original_matrix_list): 
     unit_of_work = [i, matrix] 
     work_list.append(unit_of_work) 

    work_result = run(work_list) 

所以work_result应保存所有从每个矩阵的特征值后的所有过程完成。我使用的迭代器是unit_of_work,它是一个包含矩阵索引(来自original_matrix_list)和矩阵本身的列表。

奇怪的是,如果我通过做python matrix.py运行此代码一切正常。但是当我使用auto(一个程序,它的计算微分方程解?)来运行我的脚本,打字auto matrix.py给了我以下错误:

Traceback (most recent call last): 
    File "matrix.py", line 50, in <module> 
    work_result = run(work_list) 
    File "matrix.py", line 27, in run 
    results = pool(delayed(computeEigenV)(unit_of_work) for unit_of_work in work_list) 
    File "/Library/Python/2.7/site-packages/joblib/parallel.py", line 805, in __call__ 
    while self.dispatch_one_batch(iterator): 
    File "/Library/Python/2.7/site-packages/joblib/parallel.py", line 658, in dispatch_one_batch 
    tasks = BatchedCalls(itertools.islice(iterator, batch_size)) 
    File "/Library/Python/2.7/site-packages/joblib/parallel.py", line 69, in __init__ 
    self.items = list(iterator_slice) 
    File "matrix.py", line 27, in <genexpr> 
    results = pool(delayed(computeEigenV)(unit_of_work) for unit_of_work in work_list) 
    File "/Library/Python/2.7/site-packages/joblib/parallel.py", line 162, in delayed 
    pickle.dumps(function) 
TypeError: expected string or Unicode object, NoneType found 

注:当我跑这跟auto我不得不改变if __name__ == '__main__':if __name__ == '__builtin__':

我查了一下这个错误,好像我没有正确地将迭代器unit_of_work序列化到不同的进程中。然后我尝试使用serialized_unit_of_work = pickle.dumps(unit_of_work),通过那个,当我需要使用迭代器时做pickle.loads,但我仍然得到相同的错误。

有人可以请帮助指出我在正确的方向,我该如何解决这个问题?我不愿意使用pickle.dump(obj, file[, protocol]),因为最终我将运行这个来计算数千个矩阵的特征值,而且如果可能的话,我并不想创建很多文件来存储序列化的迭代器。

谢谢! :)

回答

0

你不能在python2.7腌制迭代器(但你可以从3.4开始)。

此外,酸洗工作方式不同的__main__比在不__main__不同,它似乎auto正在做一些奇怪的与__main__。在特定对象上酸洗失败时经常会看到的是,如果不是直接运行带有对象的脚本,而是运行一个脚本作为主脚本,该脚本将“难以序列化”对象的部分脚本导入,酸洗就会成功。这是因为对象会在“困难”对象所在的命名空间级别上通过引用进行pickle ......因此它不会直接被腌制。

因此,通过添加参考图层...文件导入或类,您可能会酸洗所需的东西。但是,如果你想腌一个迭代器,除非你移动到至少python3.4,否则你运气不好。