1. 程式人生 > >python讀取GB級的文字資料,防止memoryError

python讀取GB級的文字資料,防止memoryError

由於python水平不夠,很多高效的方法不太瞭解,最近在處理大文字資料時,用老方法讀取檔案內容,容易記憶體溢位,所以找到這個教程,目前正在讀取1.5G的文字檔案。

轉載地址來源:http://chenqx.github.io/2014/10/29/Python-fastest-way-to-read-a-large-file/

感謝!!!!

 

另外自己看到一個方法是,每次讀取一部分,然後釋放變數,用的是python的gc模組。

import gc

del a(a是一個變數)

gc.collect()

 

 最近處理文字文件時(檔案約2GB大小),出現memoryError

錯誤和檔案讀取太慢的問題,後來找到了兩種比較快Large File Reading 的方法,本文將介紹這兩種讀取方法。

Preliminary

  我們談到“文字處理”時,我們通常是指處理的內容。Python 將文字檔案的內容讀入可以操作的字串變數非常容易。檔案物件提供了三個“讀”方法: .read().readline() 和 .readlines()。每種方法可以接受一個變數以限制每次讀取的資料量,但它們通常不使用變數。 .read() 每次讀取整個檔案,它通常用於將檔案內容放到一個字串變數中。然而 .read()

 生成檔案內容最直接的字串表示,但對於連續的面向行的處理,它卻是不必要的,並且如果檔案大於可用記憶體,則不可能實現這種處理。下面是read()方法示例:

 

1

2

3

4

5

6

 

try:

f = open('/path/to/file', 'r')

print f.read()

finally:

if f:

f.close()

  呼叫read()會一次性讀取檔案的全部內容,如果檔案有10G,記憶體就爆了,所以,要保險起見,可以反覆呼叫read(size)方法,每次最多讀取size個位元組的內容。另外,呼叫readline()

可以每次讀取一行內容,呼叫readlines()一次讀取所有內容並按行返回list。因此,要根據需要決定怎麼呼叫。
  如果檔案很小,read()一次性讀取最方便;如果不能確定檔案大小,反覆呼叫read(size)比較保險;如果是配置檔案,呼叫readlines()最方便:

 

1

2

 

for line in f.readlines():

process(line) # <do something with line>

Read In Chunks

  處理大檔案是很容易想到的就是將大檔案分割成若干小檔案處理,處理完每個小檔案後釋放該部分記憶體。這裡用了iter & yield

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

 

def read_in_chunks(filePath, chunk_size=1024*1024):

"""

Lazy function (generator) to read a file piece by piece.

Default chunk size: 1M

You can set your own chunk size

"""

file_object = open(filePath)

while True:

chunk_data = file_object.read(chunk_size)

if not chunk_data:

break

yield chunk_data

if __name__ == "__main__":

filePath = './path/filename'

for chunk in read_in_chunks(filePath):

process(chunk) # <do something with chunk>

Using with open()

  with語句開啟和關閉檔案,包括丟擲一個內部塊異常。for line in f檔案物件f視為一個迭代器,會自動的採用緩衝IO和記憶體管理,所以你不必擔心大檔案。

 

1

2

3

4

 

#If the file is line based

with open(...) as f:

for line in f:

process(line) # <do something with line>

Conclusion

  在使用python進行大檔案讀取時,應該讓系統來處理,使用最簡單的方式,交給直譯器,就管好自己的工作就行了。