編程學習網 > 編程語言 > 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高級編程視頻教程免費獲取