Python 导入500GB文本文件的最快方法,只需要所需的部分

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

我有大约500GB的文本文件在几个月内分开。在这些文本文件中,前43行只是连接信息(不需要)。接下来的75行是观察的描述符。接下来是4行(不需要),然后是下一个观察,即75行

我想要的就是这75行(每个观察的描述符都在同一个地方),其特征如下:

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))