我有一个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 :(得分:0)
你不能在python2.7
中腌制迭代器(但你可以从3.4
开始)。
此外,__main__
中的酸洗工作方式与__main__
中的工作方式不同,auto
似乎与__main__
做了一些奇怪的事情。当一个特定对象的pickle失败时,你经常会注意到的是,如果不是直接运行带有对象的脚本,而是运行一个脚本作为main,它将脚本的一部分导入为&#34;难以 - 序列&#34;对象,然后酸洗将成功。这是因为对象将在命名空间级别上通过引用进行pickle,其中&#34;难以&#34;对象生活......因此它永远不会被直接腌制。
所以,你可以通过添加参考层......文件导入或类来腌制你想要的东西。但是,如果你想腌制迭代器,除非你至少移动到python3.4
,否则你运气不好。