Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中使用行数作为输入变量拆分大型文本文件的快速方法_Python_Performance_Optimization_Split - Fatal编程技术网

Python中使用行数作为输入变量拆分大型文本文件的快速方法

Python中使用行数作为输入变量拆分大型文本文件的快速方法,python,performance,optimization,split,Python,Performance,Optimization,Split,我使用行数作为变量拆分文本文件。我编写此函数是为了将吐出的文件保存在临时目录中。除最后一个文件外,每个文件有400万行 import tempfile from itertools import groupby, count temp_dir = tempfile.mkdtemp() def tempfile_split(filename, temp_dir, chunk=4000000): with open(filename, 'r') as datafile:

我使用行数作为变量拆分文本文件。我编写此函数是为了将吐出的文件保存在临时目录中。除最后一个文件外,每个文件有400万行

import tempfile
from itertools import groupby, count

temp_dir = tempfile.mkdtemp()

def tempfile_split(filename, temp_dir, chunk=4000000):
    with open(filename, 'r') as datafile:
        groups = groupby(datafile, key=lambda k, line=count(): next(line) // chunk)
        for k, group in groups:
            output_name = os.path.normpath(os.path.join(temp_dir + os.sep, "tempfile_%s.tmp" % k))
            for line in group:
                with open(output_name, 'a') as outfile:
                    outfile.write(line)
主要问题是这个函数的速度。为了将一个800万行的文件拆分为两个400万行的文件,我的windows操作系统和Python 2.7的时间超过30分钟

       for line in group:
            with open(output_name, 'a') as outfile:
                outfile.write(line)
正在打开文件,并为组中的每一行写入一行。 这太慢了

相反,每组写一次

            with open(output_name, 'a') as outfile:
                outfile.write(''.join(group))

刚刚用一个800万行文件(正常运行时间行)做了一个快速测试,以运行文件的长度,并将文件分成两半。基本上,一次通过获取行计数,第二次通过执行拆分写入

在我的系统上,执行第一次传球的时间约为2-3秒。要完成拆分文件的运行和写入,所用的总时间不到21秒

没有在OP的帖子中实现lamba函数。下面使用的代码:

#!/usr/bin/env python

import sys
import math

infile = open("input","r")

linecount=0

for line in infile:
    linecount=linecount+1

splitpoint=linecount/2

infile.close()

infile = open("input","r")
outfile1 = open("output1","w")
outfile2 = open("output2","w")

print linecount , splitpoint

linecount=0

for line in infile:
    linecount=linecount+1
    if ( linecount <= splitpoint ):
        outfile1.write(line)
    else:
        outfile2.write(line)

infile.close()
outfile1.close()
outfile2.close()
#/usr/bin/env python
导入系统
输入数学
填充=打开(“输入”,“r”)
行数=0
对于填充中的线:
linecount=linecount+1
拆分点=行数/2
infle.close()
填充=打开(“输入”,“r”)
出口1=打开(“出口1”,“w”)
出口2=打开(“出口2”,“w”)
打印行数,拆分点
行数=0
对于填充中的线:
linecount=linecount+1
如果(linecount可以直接在上下文管理器中使用:

import tempfile
import time
from itertools import groupby, count

def tempfile_split(filename, temp_dir, chunk=4*10**6):
    fns={}
    with open(filename, 'r') as datafile:
        groups = groupby(datafile, key=lambda k, line=count(): next(line) // chunk)
        for k, group in groups:
            with tempfile.NamedTemporaryFile(delete=False,
                           dir=temp_dir,prefix='{}_'.format(str(k))) as outfile:
                outfile.write(''.join(group))
                fns[k]=outfile.name   
    return fns                     

def make_test(size=8*10**6+1000):
    with tempfile.NamedTemporaryFile(delete=False) as fn:
        for i in xrange(size):
            fn.write('Line {}\n'.format(i))

    return fn.name        

fn=make_test()
t0=time.time()
print tempfile_split(fn,tempfile.mkdtemp()),time.time()-t0   

在我的计算机上,
tempfile\u split
部分运行时间为3.6秒。它是OS X。

如果您在linux或unix环境中,您可以在python内部进行一些欺骗并使用
split
命令。这对我来说很有帮助,而且速度也很快:

def split_file(file_path, chunk=4000):

    p = subprocess.Popen(['split', '-a', '2', '-l', str(chunk), file_path,
                          os.path.dirname(file_path) + '/'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    p.communicate()
    # Remove the original file if required
    try:
        os.remove(file_path)
    except OSError:
        pass
    return True

感谢unutbu。行是一个字符串。我可以将“a”更改为“w”吗?是的,您可以将
a
更改为
w
。a和“w”之间是否存在“速度”差异?嘿,unutbu将outfile.write(''.join(group))更改为outfile.write(line),因为使用该函数可以为每行保存一个文件(~800万个文件)Gianni,保留
outfile.write(''.join(group))
并完全删除组中行的
。也许可以解释一下为什么使用上下文管理器会改变事情?