Python,读取许多文件并合并结果

时间:2012-07-26 14:56:04

标签: python parallel-processing multiprocessing

我可能会问一个非常基本的问题,但我真的无法想象如何在python中创建一个简单的并行应用程序。 我在一个16核的机器上运行我的脚本,我想有效地使用它们。我有16个巨大的文件要读取,我希望每个cpu读取一个文件,然后合并结果。 在这里,我举一个简单的例子说明我想做什么:

  parameter1_glob=[]
  parameter2_glob[]


  do cpu in arange(0,16):
      parameter1,parameter2=loadtxt('file'+str(cpu)+'.dat',unpack=True)

      parameter1_glob.append(parameter1)
      parameter2_glob.append(parameter2)

我认为multiprocessing模块可能会有所帮助,但我无法理解如何将其应用于我想要做的事情。

3 个答案:

答案 0 :(得分:2)

我同意Colin Dunklau在评论中所说的,这个过程会在读取和写入这些文件时遇到瓶颈,CPU需求很小。即使你有17个专用驱动器,你也不会想到一个核心。另外,虽然我意识到这与你的实际问题相关,你可能会遇到这些“巨大”文件的内存限制 - 将16个文件作为数组加载到内存中,然后将它们组合到另一个文件中几乎肯定会占用更多内存。你有。

您可以找到更好的结果来查看shell脚本这个问题。特别是,GNU sort使用内存高效的合并排序来快速排序一个或多个文件 - 比使用Python或大多数其他语言编写的最精心编写的应用程序快得多。

我建议避免任何类型的多线程工作,它会极大地增加复杂性,并且收益最小。确保一次将少量文件保留在内存中,否则会很快耗尽。无论如何,您绝对希望在两个单独的磁盘上运行读写操作。与同时读取和写入同一磁盘相关的减速非常痛苦。

答案 1 :(得分:1)

您想逐行合并吗?对于I / O绑定应用程序,有时协程程序比传统的多任务处理更有趣。您可以为所有类型的路由,合并和广播链接生成器和协同程序。用这个nice presentation by David Beazley吹响你的想法。

您可以使用协程作为接收器(未经测试,请参阅dabeaz示例):

# A sink that just prints the lines
@coroutine
def printer():
    while True:
        line = (yield)
        print line,

sources = [
    open('file1'),
    open('file2'),
    open('file3'),
    open('file4'),
    open('file5'),
    open('file6'),
    open('file7'),
]

output = printer()
while sources:
    for source in sources:
        line = source.next()
        if not line: # EOF
            sources.remove(source)
            source.close()
            continue
        output.send(line)

答案 2 :(得分:0)

假设每个文件的结果都很小,您可以使用我的包jug执行此操作:

from jug import TaskGenerator
loadtxt = TaskGenerator(loadtxt)

parameter1_glob=[]
parameter2_glob[]

@TaskGenerator
def write_parameter(oname, ps):
    with open(oname, 'w') as output:
        for p in ps:
            print >>output, p

parameter1_glob = []
parameter2_glob = []

for cpu in arange(0,16):
    ps = loadtxt('file'+str(cpu)+'.dat',unpack=True)
    parameter1_glob.append(ps[0])
    parameter2_glob.append(ps[1])

write_parameter('output1.txt', parameter1_glob)
write_parameter('output2.txt', parameter2_glob)

现在,您可以执行多个jug execute个工作。