当前位置: 首页 > 知识库问答 >
问题:

读取一个巨大的.csv文件

仉成益
2023-03-14
def getdata(filename, criteria):
    data=[]
    for criterion in criteria:
        data.append(getstuff(filename, criteron))
    return data

def getstuff(filename, criterion):
    import csv
    data=[]
    with open(filename, "rb") as csvfile:
        datareader=csv.reader(csvfile)
        for row in datareader: 
            if row[3]=="column header":
                data.append(row)
            elif len(data)<2 and row[3]!=criterion:
                pass
            elif row[3]==criterion:
                data.append(row)
            else:
                return data

我的问题是:

>

  • 如何使其与较大的文件一起工作?

    有什么办法能让它快一点吗?

    我的电脑有8GB的RAM,运行64位Windows 7,处理器是3.40GHz(不确定你需要什么信息)。

  • 共有1个答案

    蒋原
    2023-03-14

    您正在将所有行读取到一个列表中,然后处理该列表。别那么做。

    在生成行时处理行。如果需要首先过滤数据,请使用生成器函数:

    import csv
    
    def getstuff(filename, criterion):
        with open(filename, "rb") as csvfile:
            datareader = csv.reader(csvfile)
            yield next(datareader)  # yield the header row
            count = 0
            for row in datareader:
                if row[3] == criterion:
                    yield row
                    count += 1
                elif count:
                    # done when having read a consecutive series of rows 
                    return
    

    我还简化了你的过滤器测试;逻辑是一样的,但更简洁。

    import csv
    from itertools import dropwhile, takewhile
    
    def getstuff(filename, criterion):
        with open(filename, "rb") as csvfile:
            datareader = csv.reader(csvfile)
            yield next(datareader)  # yield the header row
            # first row, plus any subsequent rows that match, then stop
            # reading altogether
            # Python 2: use `for row in takewhile(...): yield row` instead
            # instead of `yield from takewhile(...)`.
            yield from takewhile(
                lambda r: r[3] == criterion,
                dropwhile(lambda r: r[3] != criterion, datareader))
            return
    
    def getdata(filename, criteria):
        for criterion in criteria:
            for row in getstuff(filename, criterion):
                yield row
    

    现在直接在代码中的getData()上循环:

    for row in getdata(somefilename, sequence_of_criteria):
        # process row
    

    您现在只在内存中保留一行,而不是每个标准保留数千行。

    yield使一个函数成为生成器函数,这意味着在您开始对其进行循环之前,它不会执行任何工作。

     类似资料:
    • 问题内容: 我目前正在尝试从Python 2.7中的.csv文件中读取数据,该文件最多包含100万行和200列(文件范围从100mb到1.6gb)。对于少于300,000行的文件,我可以(非常缓慢地)执行此操作,但是一旦超过该行,就会出现内存错误。我的代码如下所示: 在getstuff函数中使用else子句的原因是,所有符合条件的元素都将一起列在csv文件中,因此当我经过它们时,为了节省时间,我离

    • 问题内容: 我目前正在尝试从Python 2.7中的.csv文件中读取数据,该文件最多包含100万行和200列(文件范围从100mb到1.6gb)。对于少于300,000行的文件,我可以(非常缓慢地)执行此操作,但是一旦超过该行,就会出现内存错误。我的代码如下所示: 在getstuff函数中使用else子句的原因是,所有符合条件的元素都将一起列在csv文件中,因此,经过它们以节省时间时,我离开了循

    • 我想用Java读取一个巨大的文件。它包括75,000,000条线路。问题是,即使我使用的是最大和限制,但我得到的是:`java.lang.OutOfMemoryError(GC开销限制已超过),它显示这一行导致错误: 我做了一些测试,看到我能很好地阅读15,000,000行。因此我开始使用这种代码: 这里,它很好地写出了第一个15,000,000行,但是在第二个试验中,这再次给出了相同的错误,尽管

    • 问题内容: 我有一个很大的csv文件,因此无法将它们全部读入内存。我只想阅读和处理其中的几行内容。所以我正在Pandas中寻找一个可以处理此任务的函数,基本的python可以很好地处理此任务: 但是,如果我在熊猫中这样做,我总是会读第一行: 我正在寻找一些更简单的方法来处理熊猫中的这项任务。例如,如果我想读取1000到2000的行。如何快速执行此操作? 我想使用熊猫,因为我想将数据读入数据框。 问

    • 问题内容: 我有一个很大的CSV文件(15 Gb),我需要从中读取大约一百万行。据我所见-并实现-Python中的CSV实用程序仅允许在文件中顺序迭代。 将所有文件读入内存以使用一些随机选择非常耗费内存,并且遍历所有文件并丢弃一些值并选择其他值非常耗时,因此, 无论如何 , 是否有必要从CSV文件中选择一些随机行,只读那行? 我尝试没有成功: CSV文件示例: 问题答案: 正如@AndreBoos

    • 我有一个csv文件,它一直增长到大约48M行。 在向它添加新行之前,我需要阅读最后一行。 我尝试了下面的代码,但它太慢了,我需要一个更快的替代方案: