Python學習筆記:pandas.read_csv分塊讀取大文件(chunksize、iterator=True)


一、背景

日常數據分析工作中,難免碰到數據量特別大的情況,動不動就2、3千萬行,如果直接讀進 Python 內存中,且不說內存夠不夠,讀取的時間和后續的處理操作都很費勁。

Pandasread_csv 函數提供2個參數:chunksize、iterator ,可實現按行多次讀取文件,避免內存不足情況。

使用語法為:

* iterator : boolean, default False
返回一個TextFileReader 對象,以便逐塊處理文件。

* chunksize : int, default None
文件塊的大小, See IO Tools docs for more informationon iterator and chunksize.

測試數據文件構建:

import pandas as pd
import numpy as np
import os
os.chdir(r'C:\Users\111\Desktop')

np.random.seed = 2021
df_size = 1000 # 10000000

df = pd.DataFrame({
    'a': np.random.rand(df_size),
    'b': np.random.rand(df_size),
    'c': np.random.rand(df_size),
    'd': np.random.rand(df_size),
    'e': np.random.rand(df_size)
    })
df.head()
df.to_csv('data.csv')

二、指定 chunksize 分塊讀取文件

pandas.read_csv 參數 chunksize 通過指定一個分塊大小(每次讀取多少行)來讀取大數據文件,可避免一次性讀取內存不足,返回的是一個可迭代對象 TextFileReader

import pandas as pd
reader = pd.read_csv('data.csv', sep=',', chunksize=10)
# <pandas.io.parsers.TextFileReader at 0x1fc81f905e0>

for chunk in reader:
    # df = chunk
    # 對 chunk 進行數據處理
    print(type(chunk), chunk.shape)
'''
<class 'pandas.core.frame.DataFrame'> (10, 6)
<class 'pandas.core.frame.DataFrame'> (10, 6)
<class 'pandas.core.frame.DataFrame'> (10, 6)
<class 'pandas.core.frame.DataFrame'> (10, 6)
<class 'pandas.core.frame.DataFrame'> (10, 6)
'''

for chunk in reader:
    # df = chunk
    # 對 chunk 進行數據處理
    chunk.rename(columns={'Unnamed: 0':'index2'}, inplace=True) # 修改列名
    print(chunk.columns)

三、指定 iterator=True

指定 iterator=True 也可以返回一個可迭代對象 TextFileReader

iterator=Truechunksize 可以同時指定使用。

reader = pd.read_csv('data.csv', sep=',', iterator=True)
data = reader.get_chunk(5) # 返回N行數據塊
data
'''
   Unnamed: 0         a         b         c         d         e
0           0  0.289972  0.717806  0.886283  0.522148  0.976798
1           1  0.254952  0.048073  0.464765  0.138978  0.983041
2           2  0.634708  0.533182  0.855981  0.456156  0.620018
3           3  0.812648  0.024870  0.536520  0.894937  0.102704
4           4  0.699629  0.038305  0.379534  0.876242  0.906875
'''
  • get_chunk(size) -- 返回一個N行的數據塊
  • 每次執行獲取N行數據,再次執行,獲取下一個數據塊
filePath = r'data_csv.csv'
f = open(filePath, encoding='utf-8')
reader = pd.read_csv(f, sep=',', iterator=True)
data1 = reader.get_chunk(5)
data2 = reader.get_chunk(6)
f.close()

讀取未知數據文件(超大文件,幾GB)前幾行,進行數據類型觀察、列標簽觀察等。

四、其他技巧

1.獲取文件行數

count = 0
file = open('data_csv.csv', 'r', encoding='utf-8')
while 1:
    buffer = file.read(8*1024*1024) # 可大概設置
    if not buffer:
        break
    count += buffer.count('\n')
print(count)
file.close()

再根據行數估算內存可讀進多少數據,將原始數據進行划分為多少塊?

2.分塊拆分文件

import pandas as pd
reader = pd.read_csv('data_csv.csv', sep=',', chunksize=2000000)
for i, chunk in enumerate(reader):
    print(i, '  ', len(chunk))
    chunk.to_csv('./data/data_' + str(i) + '.csv', index=False)

Python 路徑加一點是當前路徑,加兩點是上一級路徑。

3.合並數據

import pandas as pd
df = [pd.read_csv('./data/data_' + str(i) + '.csv') for i in range(5)] # 列表推導式
data = pd.concat(df, axis=0).reset_index(drop=True) # 合並
data.head()
data.tail()

axis = 0 時,pd.concat 實現列對齊合並。

4.分塊讀取文件

import feather
import pandas as pd

filePath = r'data_csv.csv'

def read_csv_feature(filePath):
    # 讀取文件
    f = open(filePath, encoding='utf-8')
    reader = pd.read_csv(f, sep=',', iterator=True)
    loop = True
    chunkSize = 1000000
    chunks = []
    while loop:
        try:
            chunk = reader.get_chunk(chunkSize)
            chunks.append(chunk)
        except StopIteration:
            loop = False
            print('Iteration is END!!!')
    df = pd.concat(chunks, axis=0, ignore_index=True)
    f.close()
    return df 

data = read_csv_feature(filePath)

參考鏈接:pandas.read_csv——分塊讀取大文件

參考鏈接:使用Pandas分塊處理大文件

參考鏈接:pandas使用chunksize分塊處理大型csv文件

參考鏈接:pandas.read_csv參數詳解

參考鏈接:Python chunk讀取超大文件

參考鏈接:利用feather快速處理大數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM