我正在从MATLAB迁移到
Python,主要是因为
Python中提供了大量有趣的机器学习包.但是,对我来说混淆的一个问题是并行处理.特别是,我想在for循环中从磁盘读取数千个文本文件,我想并行执行.在MATLAB中,使用parfor代替for将会有所作为,但到目前为止我还没有弄清楚如何在python中做到这一点.
这是我想要做的一个例子.我想读取N个文本文件,将它们整形为N1xN2数组,并将每个文件保存为NxN1xN2 numpy数组.这个数组将是我从函数返回的数组.假设文件名是file0001.dat,file0002.dat等,我想并行化的代码如下:
import numpy as np
N=10000
N1=200
N2=100
result = np.empty([N, N1, N2])
for counter in range(N):
t_str="%.4d" % counter
filename = 'file_'+t_str+'.dat'
temp_array = np.loadtxt(filename)
temp_array.shape=[N1,N2]
result[counter,:,:]=temp_array
我在群集上运行代码,因此我可以使用许多处理器来完成工作.因此,任何关于哪种并行化方法更适合我的任务(如果有多个)的评论都是最受欢迎的.
注意:我知道这个post,但在那篇文章中,只有out1,out2,out3变量需要担心,并且它们已经被明确地用作要并行化的函数的参数.但是在这里,我有许多2D数组应该从文件中读取并保存到3D数组中.所以,这个问题的答案对我的情况来说不够普遍(或者我理解它的方式).
最佳答案 您仍然可能希望使用多处理,只是稍微改变它的结构:
from multiprocessing import Pool
import numpy as np
N=10000
N1=200
N2=100
result = np.empty([N, N1, N2])
filenames = ('file_%.4d.dat' % i for i in range(N))
myshaper = lambda fname: np.loadtxt(fname).reshape([N1, nN2])
pool = Pool()
for i, temparray in enumerate(pool.imap(myshaper, filenames)):
result[i, :, :] = temp_array
pool.close()
pool.join()
这样做首先得到文件名中文件名的生成器.这意味着文件名不会存储在内存中,但您仍然可以循环它们.接下来,它创建一个lambda函数(相当于matlab中的匿名函数),用于加载和重塑文件(您也可以使用普通函数).然后,它使用多个进程将该函数应用于每个文件名,并将结果放入整个数组中.然后它关闭进程.
这个版本使用了一些更惯用的python.但是,一种与原始方法更相似的方法(虽然不那么惯用)可能会帮助您更好地理解:
from multiprocessing import Pool
import numpy as np
N=10000
N1=200
N2=100
result = np.empty([N, N1, N2])
def proccounter(counter):
t_str="%.4d" % counter
filename = 'file_'+t_str+'.dat'
temp_array = np.loadtxt(filename)
temp_array.shape=[N1,N2]
return counter, temp_array
pool = Pool()
for counter, temp_array in pool.imap(proccounter, range(N)):
result[counter,:,:] = temp_array
pool.close()
pool.join()
这只是将你的大部分for循环分成一个函数,使用多个处理器将该函数应用于范围的每个元素,然后将结果放入数组中.它基本上只是你的原始函数,for循环分为两个for循环.