编程学习网 > 编程语言 > Python > Python处理大文件的五种方法,各有千秋!
2024
06-15

Python处理大文件的五种方法,各有千秋!

Python在文件处理方面具有强大的支持。然而,当处理大型文件时,由于可能出现高内存使用量的情况,标准的文件处理技术可能不够高效。

在Python中打开大型文件有各种用例,特别是在数据分析、机器学习和系统管理等领域中常见的大型数据集。以下是一些示例:

数据分析和机器学习:这些领域通常涉及到大型数据集。例如,您可能正在处理一个多GB大小的日志文件或一个包含用于机器学习模型训练的大型CSV文件。

在这种情况下,您需要高效地打开和处理这些文件,并且通常需要逐块或逐行读取以适应内存。

文本处理:如果您正在处理像书籍、网页转储或大批量客户评论之类的大文本文件,则需要打开这些文件执行搜索、替换或计数等操作。

日志分析:系统管理员经经常使用大型服务器日志文件来诊断问题、监控系统性能或分析用户行为。Python凭借其强大的文本处理功能可以成为此工作的优秀工具。

在本文中,编程君将概述一些在Python中处理大型文件时最佳实践方法,确保对数据进行高效且安全地管理。

1使用with语句

Python中的with语句提供了一种清晰高效的处理文件的方式。它管理文件的打开和关闭,即使在块内部发生异常也能正确处理。

这降低了文件泄漏的风险,因为如果一个文件在使用后没有被正确关闭,就可能会发生泄漏。

with open('large_file.txt', 'r') as file:

    for line in file:

        print(line)

使用with语句,您无需显式关闭文件;一旦退出with代码块,它会自动关闭。在上面的代码中,您正在打开一个文件并逐行迭代。

当您像这样在for循环中使用文件对象时,Python每次从文件中读取一行,并对其进行处理,然后继续下一行。这样做是为了避免处理大型文件时出现内存问题。

open函数返回一个文件对象,并且正是将该文件对象分配给了with语句中的变量file。在with块内部,使用for循环逐行读取该文件。

当通过for循环迭代文件对象时,Python对于每次迭代都调用该文件对象的__next__()方法。此方法每次被调用时都会读取并返回来自该文件的下一行。

如果没有更多的行存在于该文件中,则__next__()方法引发StopIteration异常,这向for循环发出停止迭代的信号。

例如:

class SimpleFile():

    def __init__(self, data):

        self.data = data.splitlines()

        self.index = -1


    def __iter__(self):

        return self

    def __next__(self):

        self.index += 1

        if self.index < len(self.data):

            return self.data[self.index]

        else:

            raise StopIteration

data = "line 1\nline 2\nline 3\nline4"

my_file = SimpleFile(data)

while True:

    print(next(my_file))

当您运行上述代码时,您将看到以下内容:

line 1

line 2

line 3

line4

Traceback (most recent call last):

  File "/mnt/efs/awside/data/home/lxu1/code/tony/python-code/file_opener.py", line 21, in <module>

    print(next(my_file))

          ^^^^^^^^^^^^^

  File "/mnt/efs/awside/data/home/lxu1/code/tony/python-code/file_opener.py", line 14, in __next__

    raise StopIteration

StopIteration

2懒加载文件

处理大型文件时,不要一次性将整个文件加载到内存中。相反,应该逐行或分块读取文件。这种方法被称为懒加载。

with open('large_file.txt', 'r') as file:

    while True:

        line = file.readline()

        if not line:

            break 

        print(line)

# 或者使用海象运算符

with open('large_file.txt', 'r') as file:

    while line := file.readline():

        print(line)

在Python中,readline()方法用于从文件中读取一行。以下是readline()的简要概述:

调用时,它会读取文件的下一行并将其作为字符串返回。

返回的字符串包括换行符\n(如果存在)。

如果再次调用该方法,它将读取下一行。

当到达文件末尾时,readline()将返回一个空字符串。

在上面的代码中,它逐行读取文件并打印每一行。它被设计成能够高效处理大型文件,而不会一次性加载整个文件到内存中。它继续读取和打印行直到达到文件末尾,在此处跳出循环并完成执行。

3使用生成器

生成器允许您在不一次性加载整个文件到内存中的情况下迭代大型文件。它们逐行产生数据并在迭代之间保持其状态,使其成为处理大量数据的高效工具。例如:

def read_large_file(file_object):

    while True:

        data = file_object.readline()

        if not data:

            break

        yield data

with open('large_file.txt', 'r') as file:

    gen = read_large_file(file)

    for line in gen:

        print(line)

在上面的代码中:

yield data:如果有数据,函数会将其生成。这使得该函数成为一个生成器,在Python中是一种特殊类型的函数,它产生一系列结果而不是单个值。

gen = read_large_file(file):通过使用文件对象调用read_large_file函数来创建一个生成器对象。

for line in gen:这个循环遍历生成器(逐行从文件中产生结果)。

4以块方式读取文件

在Python中,以块方式读取大文件是处理大文件的常见技术。这样可以一次处理文件的部分内容,减少内存使用量。

chunk_size = 1024  # 在每次迭代中读取1024字节

with open('large_file.txt', 'r') as file:

    while True:

        chunk = file.read(chunk_size)

        if not chunk: # 该块为空,这意味着我们已经到达文件的末尾。

            break

        print(chunk)

5使用外部库

对于非常大的文件或复杂的数据处理,考虑使用像Pandas或Dask这样的库。这些库不仅提供了高效的数据结构用于数据操作,还提供了处理超过内存大小的数据集的功能。

以下如何使用Pandas以块方式读取大型CSV文件:

import pandas as pd

chunk_size = 500 

chunks = []

for chunk in pd.read_csv('large_file.csv', chunksize=chunk_size):

    chunks.append(chunk)

df = pd.concat(chunks, axis=0)

在这个例子中,pd.read_csv()函数每次读取500行,并返回一个包含这些行的DataFrame,然后可以分别处理。

总之,在Python中高效处理大文件是许多编程任务的重要技能,特别是在数据分析、机器学习和系统管理等领域。

通过理解和利用最佳实践,如使用with语句进行自动文件管理、惰性或按块读取文件、利用生成器的强大功能、避免不必要的引用以及利用Pandas等外部库,您可以确保您的Python程序高效、健壮,并且能够轻松处理大型数据集。

以上就是Python处理大文件的五种方法,各有千秋!的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取