我需要在DATE之前拆分一个大的txt文件(大约100GB, 10亿行)。该文件看起来像这样
ID*DATE*company
1111*201101*geico
1234*201402*travelers
3214*201003*statefarm
...
基本上有60个月,所以我应该得到60个子文件。我的Python脚本是
with open("myBigFile.txt") as f:
for line in f:
claim = line.split("*")
with open("DATE-"+str(claim[1])+".txt", "a") as fy:
fy.write(claim[0]+"*"+claim[2]+"\n")
现在由于记录数量巨大,因此需要为每一行打开/关闭文件,因此运行速度太慢。所以我在考虑首先打开60个子文件,然后扫描文件,将每一行写入相应的子文件。 在扫描所有行之前,子文件不会关闭。但是,由于python会在删除引用时自动关闭文件(http://blog.lerner.co.il/dont-use-python-close-files-answer-depends/),所以我必须使用一些动态文件名,例如
claim[1].write(claim[0]+"*"+claim[2]+"\n")
请注意,您无法命名fy
和fy.write(claim[0]+"*"+claim[2]+"\n")
,因为只要fy
发生更改,它就会关闭文件。这可能在Python中吗?谢谢!
答案 0 :(得分:0)
这样的事情怎么样:
with open("myBigFile.txt") as f:
subfiles = {}
for line in f:
claim = line.split("*")
if not str(claim[1]) in subfiles:
subfiles[str(claim[1])] = open("DATE-" + str(claim[1]) + ".txt", "a")
subfile[str(claim[1])].write(claim[0]+"*"+claim[2]+"\n")
我相信这应该做到。
请注意,我目前没有限制在特定时刻打开的文件数量。要实现这一点,只需使用'len()'检查列表的大小,然后关闭所有文件或几个文件。
答案 1 :(得分:0)
您可以使用csv
模块略微简化,并使用字典存储文件对象:
import csv
with open("myBigFile.txt") as big_file:
reader = csv.reader(big_file, delimiter='*')
subfiles = {}
for id, date, company in reader:
try:
subfile = subfiles[date]
except KeyError:
subfile = open('DATE-{}.txt'.format(date), 'a')
subfiles[date] = subfile
subfile.write('{}*{}\n'.format(id, company))
for subfile in subfiles.values():
subfile.close()
答案 2 :(得分:0)
这是一个将文件句柄作为上下文管理器的一部分关闭的解决方案,与其他答案不同,这也会在发生错误时关闭子文件: - )
from contextlib import contextmanager
@contextmanager
def file_writer():
fp = {}
def write(line):
id, date, company = line.split('*')
outdata = "{}*{}\n".format(id, company)
try:
fp[date].write(outdata)
except KeyError:
fname = 'DATE-{}.txt'.format(date)
fp[date] = open(fname, 'a') # should it be a+?
fp[date].write(outdata)
yield write
for f in fp.values():
f.close()
def process():
with open("myBigFile.txt") as f:
with file_writer() as write:
for i, line in enumerate(f):
try:
write(line)
except:
print('the error happened on line %d [%s]' % (i, line))
我不知道在单个处理器/磁盘上是否还有更多可以快速完成的工作。您始终可以将文件拆分为n个块并使用n个进程来处理每个块(其中n是您可用的单独磁盘的数量......)