Python 导入500GB文本文件的最快方法,只需要所需的部分
我有大约500GB的文本文件在几个月内分开。在这些文本文件中,前43行只是连接信息(不需要)。接下来的75行是观察的描述符。接下来是4行(不需要),然后是下一个观察,即75行 我想要的就是这75行(每个观察的描述符都在同一个地方),其特征如下:Python 导入500GB文本文件的最快方法,只需要所需的部分,python,text,replace,Python,Text,Replace,我有大约500GB的文本文件在几个月内分开。在这些文本文件中,前43行只是连接信息(不需要)。接下来的75行是观察的描述符。接下来是4行(不需要),然后是下一个观察,即75行 我想要的就是这75行(每个观察的描述符都在同一个地方),其特征如下: ID: 5523 Date: 20052012 Mixed: <Null> . . import linecache filename = 'observations1.txt' # Start at 44th line curline
ID: 5523
Date: 20052012
Mixed: <Null>
.
.
import linecache
filename = 'observations1.txt'
# Start at 44th line
curline = 44
lines = []
# Keep looping until no return string is found
# getline() never throws errors, but returns an empty string ''
# if the line wasn't found (if the line was actually empty, it would have
# returned the newline character '\n')
while linecache.getline(filename, curline):
for i in xrange(75):
lines.append(linecache.getline(filename, curline).rstrip())
curline += 1
# Perform work with the set of observation lines
add_to_observation_log(lines)
# Skip the unnecessary section and reset the lines list
curline += 4
lines = []
ID:5523
日期:20052012
混合的:
.
.
我想把它改成csv格式5523;20052012;;..代码>用于每次观察。这样我就得到了更小的文本文件。由于描述符是相同的,我将知道第一个位置,例如ID
一旦我完成了文本文件,我将打开下一个并附加它(或者创建一个新文件会更快吗?)
我的工作效率很低,因为我一直在打开文件。加载它。逐行删除这些观察结果。如果用一个测试样本进行测试的话,这显然不是最好的方法
任何建议都很好 您说您有“大约500GB的文本文件”。如果我理解正确,您没有为每个观察设置固定长度(请注意,我不是说行数,我指的是观察所有行的总长度,以字节为单位)。这意味着您必须浏览整个文件,因为您无法确切知道换行符将出现在哪里
现在,根据每个文本文件的大小,您可能需要寻找不同的答案。但是,如果每个文件足够小(小于1GB?),您可能可以使用该模块,它可以为您处理逐行查找
您可能会这样使用它:
ID: 5523
Date: 20052012
Mixed: <Null>
.
.
import linecache
filename = 'observations1.txt'
# Start at 44th line
curline = 44
lines = []
# Keep looping until no return string is found
# getline() never throws errors, but returns an empty string ''
# if the line wasn't found (if the line was actually empty, it would have
# returned the newline character '\n')
while linecache.getline(filename, curline):
for i in xrange(75):
lines.append(linecache.getline(filename, curline).rstrip())
curline += 1
# Perform work with the set of observation lines
add_to_observation_log(lines)
# Skip the unnecessary section and reset the lines list
curline += 4
lines = []
我尝试了一个测试,它在五秒钟内浏览了一个23MB的文件
打开文件。加载它。逐行删除这些观察结果
“加载”是什么意思?如果你的意思是把整个东西读成一个字符串,那么是的,这会很糟糕。处理文件的自然方式是利用文件对象是文件行上的迭代器这一事实:
for line in file:
if should_use(line): do_something_with(line)
你应该考虑把你想要保存的信息写入数据库。在python中,可以使用内置的sqlite3。这是很容易理解的
您说您现在可以精确地保存每个文件中要保留的行。你可以试试这样的
import csv
reader = csv.reader(open("afile.csv","rb"),delimiter="\t",quotechar='"')
info_to_keep = []
obs = []
for row in reader:
i+=1
if i<43:
continue
elif i-43 <79*(len(info_to_keep)+1)-4:
obs.append(row)
elif i-43 <79*(len(info_to_keep)+1):
continue
else:
info_to_keep.append(obs)
obs = [row]
导入csv
reader=csv.reader(打开(“afile.csv”、“rb”),分隔符=“\t”,引号=”)
信息保存=[]
obs=[]
对于读取器中的行:
i+=1
如果你的文件中有固定长度的部分吗?是的,因此它的名字是:你能发布你的样本代码吗?这是一个需要花费一些时间来处理最终数据集样本的代码。不,它们不是,但是每个观察都在一个单独的行上。所以ID有一行,然后下一行是日期,依此类推。(抱歉,我刚刚意识到问题的格式不正确)@ColeJohnson,@voithos:不太正确。请阅读(#3)还有。请注意一个分隔符关键字参数。感谢您引导我进入这个模块。数据大约1GB有时会稍大一些,但我认为这应该适用于它的大小。我试图避免使用列表的原因是我在编写列表时遇到了问题。使用您的代码,我很快将其改编为适合我的用途:while linecache.getline(文件名,卷曲线):对于范围(75)中的i:data_-operated=linecache.getline(文件名,卷曲线).rstrip()datamanipulated2=data_-operated.split(“:”)datamanipulated2.pop(0)行。追加(datamanipulated2)curline+=1/*并将open('outputfile',“a”)作为f:#f.write(行)/*这会给您一个错误,即“list”对象没有“write”属性,因此我决定聪明一点……并尝试了以下操作:f=print(“,”.join(map(str,lines)))然后您会得到以下错误类型错误:必须是str,而不是_io.TextIOWrapper我觉得awnser非常简单,但我没有找到它,有什么建议吗?再次感谢linecache模块。@FancyDolphin:看来您对键不感兴趣(ID:
,日期:
,等等)并且只想提取数据。那很好。至于写出来,只需在列表上迭代并写出来。另外,将来,当您需要在注释中发布代码时,将其放在或类似的工具上,然后只发布一个链接。这样更容易阅读。@FancyDolphin:错误意味着您的数据在某个点上有多个冒号,并且是错误的将拆分为两个以上的值。如果是这种情况,则pop()
应该可以工作,但不要对结果列表执行append()
操作,而是尝试附加该结果的联接,即lines.append(“:”.join(datamanufactured2))