在处理大文件时,如何快速得到一行中的多个列?

2024-10-02 18:22:04 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个有5000列和1000000行的大文件。一行中的列由\t分隔,每个单元格都是几乎随机长度的字符串。我希望访问每行中的特定列并对它们进行评估。通常的方法太慢了。我写了一个这样的代码来固定细胞:

def amk(theLine, delimiter, columnList):
    ind = -1
    for col in columnList:
        for _ in range(col):
            ind = theLine.find(delimiter, ind + 1)
        yield theLine[ind + 1: theLine.find(delimiter, ind + 1)]

def columnListProcessor(columnList):
    columnList.sort(reverse=False)
    return [columnList[0]] + [columnList[i] - columnList[i - 1] for i in range(1,len(columnList))]

# Let's use a random columns to process for here.
# Amount of column can be more than 500
columnList = columnListProcessor([1, 3, 31, 232, 443, 514, 801, 1032, 1500, 2540, 2983, 3500, 4000, 4441, 4982])

with open("hugeFile.txt", "r") as theFile:
    theLine = theFile.readline()
    while theLine:
        for k in amk(theLine, "\t", columnList):
            if condition:
                foo()
        theLine = theFile.readline()

我可以说这其实相当快。但是,我意识到函数amk可以更好。当它产生结果时,它执行theLine.find(delimiter, ind + 1),这样它就会找到下一个\t。但是,它不会保存下一个\t的索引,因此下次调用它以生成列表中的下一列时,它会再次执行theLine.find(delimiter, ind + 1)以查找下一个\t。我的意思是它会发现下一个\t两次,这会导致我的代码运行较慢

我试图创建一个新的索引生成器,其中包含theLine.find(delimiter, ind + 1),但它并没有加快进程,尽管我可能写得不好。我不能解决这个问题,我不能紧固代码,虽然它显然可以更快地工作


Tags: 代码inforreadlinedefrangecolfind
1条回答
网友
1楼 · 发布于 2024-10-02 18:22:04

如果您想要5000列中的500列,那么使用分隔符拆分所有列似乎更合适:

def amk(line, delimiter, column_list):
    split_line = line.split(delimiter)
    for col in column_list:
        yield split_line[col]

column_list = [1, 3, 31, 232, 443, 514, 801, 1032, 1500, 2540, 2983, 3500, 4000, 4441, 4982]

with open("hugeFile.txt", "r") as fobj:
    for line in fobj:
        for k in amk(line, "\t", column_list):
            print(k)

字符串的.split()方法是用C实现的。因此,它真的很快。即使使用.find()进行较少的搜索,也需要从Python多次调用它。与C中的一个函数(方法)调用相比,多个Python函数调用速度较慢。尽管方法.find()本身也是用C实现的,但是与调用.split()的次数相比,您需要从Python多次调用它

通常,您总是需要测量运行时间。通常情况下,对于您的用例,什么方法更快并不那么明显

相关问题 更多 >