首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Python中处理大文件[ 1000 GB或更大]

在Python中处理大文件[ 1000 GB或更大]
EN

Stack Overflow用户
提问于 2014-05-21 00:33:32
回答 7查看 12.7K关注 0票数 18

假设我有一个1000 GB的文本文件。我需要找出一个短语在文本中出现的次数。

有没有比我现在使用的更快的方法呢?完成这项任务需要多少钱?

代码语言:javascript
复制
phrase = "how fast it is"
count = 0
with open('bigfile.txt') as f:
    for line in f:
        count += line.count(phrase)

如果我是对的,如果我的内存中没有这个文件,我就需要等待,直到每次我进行搜索时PC加载该文件,对于一个250MB/秒的硬盘驱动器和一个10000 GB的文件来说,这至少需要4000秒。

EN

回答 7

Stack Overflow用户

发布于 2014-05-24 07:22:27

这是一个Python尝试...您可能需要使用线程和CHUNK_SIZE。而且,它是在短时间内的一堆代码,所以我可能没有考虑到所有的事情。我确实重叠了我的缓冲区,以捕获中间的缓冲区,并且我扩展了最后一个块,以包括文件的其余部分。

代码语言:javascript
复制
import os
import threading

INPUTFILE ='bigfile.txt'
SEARCH_STRING='how fast it is'
THREADS = 8  # Set to 2 times number of cores, assuming hyperthreading
CHUNK_SIZE = 32768

FILESIZE = os.path.getsize(INPUTFILE)
SLICE_SIZE = FILESIZE / THREADS



class myThread (threading.Thread):
    def __init__(self, filehandle, seekspot):
        threading.Thread.__init__(self)
        self.filehandle = filehandle
        self.seekspot = seekspot
        self.cnt = 0
    def run(self):
        self.filehandle.seek( self.seekspot )

        p = self.seekspot
        if FILESIZE - self.seekspot < 2 * SLICE_SIZE:
            readend = FILESIZE
        else: 
            readend = self.seekspot + SLICE_SIZE + len(SEARCH_STRING) - 1
        overlap = ''
        while p < readend:
            if readend - p < CHUNK_SIZE:
                buffer = overlap + self.filehandle.read(readend - p)
            else:
                buffer = overlap + self.filehandle.read(CHUNK_SIZE)
            if buffer:
                self.cnt += buffer.count(SEARCH_STRING)
            overlap = buffer[len(buffer)-len(SEARCH_STRING)+1:]
            p += CHUNK_SIZE

filehandles = []
threads = []
for fh_idx in range(0,THREADS):
    filehandles.append(open(INPUTFILE,'rb'))
    seekspot = fh_idx * SLICE_SIZE
    threads.append(myThread(filehandles[fh_idx],seekspot ) )
    threads[fh_idx].start()

totalcount = 0 
for fh_idx in range(0,THREADS):
    threads[fh_idx].join()
    totalcount += threads[fh_idx].cnt

print totalcount
票数 8
EN

Stack Overflow用户

发布于 2014-05-24 05:04:17

您是否考虑过使用parallel / grep

代码语言:javascript
复制
cat bigfile.txt | parallel --block 10M --pipe grep -o 'how\ fast\ it\ is' | wc -l
票数 7
EN

Stack Overflow用户

发布于 2014-05-26 12:19:59

你有没有考虑过为你的文件建立索引?搜索引擎的工作方式是通过创建从单词到它们在文件中的位置的映射。假设你有这个文件:

代码语言:javascript
复制
Foo bar baz dar. Dar bar haa.

您可以创建一个如下所示的索引:

代码语言:javascript
复制
{
    "foo": {0},
    "bar": {4, 21},
    "baz": {8},
    "dar": {12, 17},
    "haa": {25},
}

哈希表索引可以在O(1)中查找;所以它非常快。

如果有人搜索查询"bar baz“,您首先将查询分解为其构成词:"bar","baz”,然后找到{4,21},{8};然后使用它跳到查询文本可能存在的位置。

索引搜索引擎也有开箱即用的解决方案;例如SolrElasticSearch

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23765360

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档