最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Pandas大規(guī)模數據分塊讀取與內存優(yōu)化的實戰(zhàn)指南

 更新時間:2025年12月05日 08:32:53   作者:傻啦嘿喲  
當Excel崩潰在處理第10萬行數據時,當Python報錯MemoryError時,數據工程師的噩夢就此開始,本文將用真實案例拆解Pandas處理大規(guī)模數據的核心技巧,需要的朋友可以參考下

引言

當Excel崩潰在處理第10萬行數據時,當Python報錯"MemoryError"時,數據工程師的噩夢就此開始。本文將用真實案例拆解Pandas處理大規(guī)模數據的核心技巧,從500MB到50GB數據集的實戰(zhàn)經驗總結,讓你用8GB內存電腦也能玩轉大數據。

一、為什么常規(guī)方法會崩潰?

1. 內存爆炸現場還原

測試環(huán)境:8GB內存筆記本,處理1000萬行CSV數據

import pandas as pd

# 錯誤示范1:直接讀取整個文件
df = pd.read_csv('large_file.csv')  # 內存占用飆升至9.2GB,程序崩潰

# 錯誤示范2:未指定數據類型
df = pd.read_csv('large_file.csv', dtype=object)  # 內存占用翻倍

典型癥狀

  • 程序卡死無響應
  • 系統(tǒng)開始瘋狂使用交換分區(qū)
  • 最終彈出"MemoryError"彈窗

2. 內存消耗計算法則

Pandas數據內存占用公式:

內存占用(MB) ≈ 行數 × 列數 × 每個值的字節(jié)數 / 10242

示例:1000萬行×20列×float64(8字節(jié)) ≈ 1.5GB

隱藏殺手

  • 字符串默認存儲為object類型(每個值單獨分配內存)
  • 日期時間列未指定dtype
  • 存在大量缺失值(NaN占用空間與數值相同)

二、分塊讀?。喊汛笙笱b進冰箱

1. chunksize參數實戰(zhàn)

# 分塊讀取示例:每次處理10萬行
chunk_size = 100000
chunks = pd.read_csv('sales_data.csv', chunksize=chunk_size)

results = []
for chunk in chunks:
    # 對每個數據塊進行處理
    chunk_processed = chunk[chunk['amount'] > 1000]
    results.append(chunk_processed)

# 合并結果(注意內存控制)
final_df = pd.concat(results, ignore_index=True)

適用場景

  • 數據量超過內存容量
  • 需要逐步處理避免峰值內存占用
  • 實時數據流處理

2. 增量寫入技巧

處理完一個數據塊后立即寫入磁盤:

with pd.HDFStore('output.h5', mode='w') as store:
    for i, chunk in enumerate(pd.read_csv('big_data.csv', chunksize=50000)):
        # 數據清洗邏輯
        cleaned = chunk.dropna(subset=['price'])
        store.append(f'chunk_{i}', cleaned, index=False)

優(yōu)勢

  • 內存占用恒定在chunksize級別
  • 支持斷點續(xù)處理
  • 最終結果可直接用Pandas讀取

3. 分塊處理案例:百萬級日志分析

需求:統(tǒng)計每個用戶的訪問次數和總時長

import pandas as pd
from collections import defaultdict

user_stats = defaultdict(lambda: {'count':0, 'duration':0})

for chunk in pd.read_csv('access_logs.csv', chunksize=100000):
    for _, row in chunk.iterrows():
        user = row['user_id']
        user_stats[user]['count'] += 1
        user_stats[user]['duration'] += row['duration']

# 轉換為DataFrame
result_df = pd.DataFrame.from_dict(user_stats, orient='index')

優(yōu)化點

  • 使用字典暫存中間結果
  • 避免在循環(huán)中創(chuàng)建DataFrame
  • 最終一次性轉換格式

三、內存優(yōu)化七種武器

1. 數據類型精準打擊

# 原始讀?。ㄗ詣油茢囝愋?,可能不最優(yōu))
df = pd.read_csv('data.csv')  # 內存占用:1.2GB

# 優(yōu)化后讀?。ㄖ付ň_類型)
dtypes = {
    'id': 'int32',
    'price': 'float32',
    'category': 'category',  # 分類數據專用類型
    'date': 'datetime64[ns]'
}
df_optimized = pd.read_csv('data.csv', dtype=dtypes)  # 內存占用:480MB

類型選擇指南

  • 整數:int8/16/32/64(根據數值范圍選擇)
  • 浮點數:float32(足夠時不用float64)
  • 字符串:category(有限取值時)
  • 布爾值:bool

2. 分類數據編碼術

# 原始字符串列(占用大)
df['product_type'] = ['A','B','A','C'...]  # 每個值重復存儲

# 轉換為分類類型(節(jié)省內存)
df['product_type'] = df['product_type'].astype('category')

# 進一步優(yōu)化:使用數值編碼
df['product_code'] = df['product_type'].cat.codes

效果對比

  • 100萬行字符串列:約200MB
  • 轉換為category:約8MB
  • 轉換為數值編碼:約4MB

3. 缺失值處理策略

# 原始缺失值(NaN占用空間)
df = pd.DataFrame({'A': [1, None, 3], 'B': [None, 'x', None]})

# 優(yōu)化方案1:用特定值填充(適合數值列)
df['A'].fillna(0, inplace=True)

# 優(yōu)化方案2:用更緊湊的類型存儲(適合字符串列)
df['B'] = df['B'].astype('category')

# 優(yōu)化方案3:直接刪除(當缺失比例高時)
df.dropna(subset=['important_column'], inplace=True)

4. 稀疏數據壓縮術

# 創(chuàng)建稀疏DataFrame(大部分值為0或空)
import numpy as np
import pandas as pd

data = np.random.choice([0, 1], size=(1000000, 100), p=[0.99, 0.01])
df = pd.DataFrame(data)

# 轉換為稀疏格式(節(jié)省95%內存)
sparse_df = df.astype(pd.SparseDtype("int8", 0))

適用場景

  • 推薦系統(tǒng)用戶-物品矩陣
  • 自然語言處理的詞頻矩陣
  • 傳感器數據中的大量零值

5. 日期時間優(yōu)化方案

# 原始讀取(自動轉為datetime64[ns])
df = pd.read_csv('transactions.csv', parse_dates=['date'])  # 8字節(jié)/值

# 優(yōu)化方案1:使用整數時間戳
df['timestamp'] = pd.to_datetime(df['date']).astype(np.int64) // 10**9  # 4字節(jié)/值

# 優(yōu)化方案2:分離年月日(當不需要完整時間時)
df['year'] = pd.to_datetime(df['date']).dt.year  # int16
df['month'] = pd.to_datetime(df['date']).dt.month  # int8

6. 列式存儲格式選擇

格式讀取速度寫入速度內存占用適用場景
CSV文本交換格式
Parquet大數據存儲
HDF5需要隨機訪問的二進制數據
Feather極快極快Pandas數據快速交換

轉換示例

# 保存為Parquet格式(壓縮比高)
df.to_parquet('data.parquet', compression='snappy')

# 讀取Parquet文件
df_parquet = pd.read_parquet('data.parquet')

7. 對象列專項治理

# 識別高內存對象列
def memory_usage(df):
    return df.memory_usage(deep=True).sort_values(ascending=False)

# 對象列優(yōu)化方案
for col in df.select_dtypes(include=['object']):
    # 嘗試轉換為category
    if df[col].nunique() / len(df) < 0.5:
        df[col] = df[col].astype('category')
    # 嘗試轉換為更緊湊的字符串表示
    elif df[col].str.len().max() < 50:
        pass  # 保持現狀或考慮數值編碼
    else:
        # 分割字符串或提取關鍵信息
        df[['part1','part2']] = df[col].str.split('|', expand=True)

四、實戰(zhàn)案例:10GB電商數據處理

1. 數據概況

  • 文件:orders_2020-2023.csv(10.2GB)
  • 行數:約8500萬行
  • 列數:18列(含用戶ID、商品ID、金額、時間等)

2. 分塊處理流程

import pandas as pd
import numpy as np

# 定義數據類型
dtypes = {
    'order_id': 'int64',
    'user_id': 'int32',
    'product_id': 'int32',
    'quantity': 'int16',
    'price': 'float32',
    'order_time': 'datetime64[ns]'
}

# 分塊處理函數
def process_chunk(chunk):
    # 數據清洗
    chunk = chunk[chunk['price'] > 0]
    chunk = chunk[chunk['quantity'] > 0]
    
    # 特征工程
    chunk['total_amount'] = chunk['price'] * chunk['quantity']
    chunk['day_of_week'] = chunk['order_time'].dt.dayofweek
    
    # 按用戶分組統(tǒng)計
    user_stats = chunk.groupby('user_id').agg({
        'total_amount': 'sum',
        'quantity': 'sum',
        'order_id': 'count'
    }).rename(columns={'order_id': 'order_count'})
    
    return user_stats

# 主處理流程
chunk_size = 500000
results = []

for i, chunk in enumerate(pd.read_csv(
    'orders_2020-2023.csv',
    dtype=dtypes,
    parse_dates=['order_time'],
    chunksize=chunk_size
)):
    print(f"Processing chunk {i+1}")
    results.append(process_chunk(chunk))

# 合并結果
final_result = pd.concat(results).groupby('user_id').sum()
final_result.to_parquet('user_stats.parquet')

3. 優(yōu)化效果對比

優(yōu)化措施內存占用處理時間輸出大小
原始讀取崩潰--
僅分塊讀取1.8GB42分鐘2.1GB
分塊+類型優(yōu)化850MB35分鐘1.8GB
分塊+類型+并行處理900MB18分鐘1.8GB

五、常見問題Q&A

Q1:處理過程中出現"DtypeWarning"怎么辦?
A:這是Pandas提示列類型推斷不準確。解決方案:

  • 顯式指定dtype參數
  • 先讀取小樣本檢查數據類型
  • 對混合類型列使用pd.to_numeric(errors='coerce')

Q2:如何判斷是否需要分塊處理?
A:簡單估算公式:

預計內存占用(GB) = 行數 × 列數 × 8字節(jié) / 10243

當結果超過可用內存的50%時,建議分塊處理。例如:

  • 8GB內存電腦:處理超過約1000萬行×20列(float64)的數據
  • 16GB內存電腦:處理約2000萬行×20列的數據

Q3:Parquet和HDF5哪個更適合我的場景?
A:選擇依據:

  • Parquet:適合:
    • 列式存儲需求
    • 需要壓縮減少存儲空間
    • 與Spark/Dask等工具交互
    • 復雜數據類型(嵌套結構)
  • HDF5:適合:
    • 需要隨機訪問特定行/列
    • 存儲大型數組數據
    • 需要追加寫入
    • 與PyTables等庫集成

Q4:如何加速分塊處理?
A:進階優(yōu)化方案:

from multiprocessing import Pool

def parallel_process(chunk):
    # 處理邏輯同前
    return process_chunk(chunk)

if __name__ == '__main__':
    chunks = pd.read_csv('big_data.csv', chunksize=100000)
    
    with Pool(processes=4) as pool:  # 使用4個CPU核心
        results = pool.map(parallel_process, chunks)
    
    final_result = pd.concat(results)

注意事項

  • 確保每個處理塊內存獨立
  • 避免全局變量沖突
  • 合理設置進程數(通常為CPU核心數)

Q5:處理完的數據如何高效可視化?
A:分階段處理:

  1. 聚合階段:在分塊處理時完成統(tǒng)計計算
  2. 采樣階段:對大數據集隨機采樣
    # 從1000萬行中采樣1%
    sample_df = df.sample(frac=0.01, random_state=42)
  3. 可視化階段:使用輕量級工具
    # 使用Plotly Express(比Seaborn更高效)
    import plotly.express as px
    fig = px.histogram(sample_df, x='price', nbins=50)
    fig.show()

六、終極優(yōu)化清單

  1. 預處理階段
    • 檢查數據是否有不必要列(直接刪除)
    • 評估是否需要全部數據(能否采樣)
    • 確認數據是否有重復行
  2. 讀取階段
    • 指定明確的dtype
    • 使用usecols選擇必要列
    • 設置parse_dates只解析需要的日期列
  3. 處理階段
    • 避免在循環(huán)中創(chuàng)建DataFrame
    • 使用向量化操作替代apply
    • 及時刪除中間變量(使用delgc.collect()
  4. 存儲階段
    • 選擇合適文件格式(Parquet優(yōu)先)
    • 啟用壓縮(snappy/gzip)
    • 考慮列式存儲優(yōu)勢

通過這套方法 論,我們成功在8GB內存筆記本上處理了15GB的電商交易數據,最終生成的分析結果僅占用280MB存儲空間。記?。捍髷祿幚淼谋举|不是硬抗內存,而是用智慧讓數據"瘦身"。

以上就是Pandas分塊讀取與內存優(yōu)化的實戰(zhàn)指南的詳細內容,更多關于Pandas分塊讀取與內存優(yōu)化的資料請關注腳本之家其它相關文章!

相關文章

  • Pandas 如何篩選包含特定字符的列

    Pandas 如何篩選包含特定字符的列

    這篇文章主要介紹了Pandas 如何篩選包含特定字符的列,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • 簡單介紹Python中的floor()方法

    簡單介紹Python中的floor()方法

    這篇文章主要介紹了Python中的floor()方法,是Python入門的基礎知識,需要的朋友可以參考下
    2015-05-05
  • Pyqt5打開電腦攝像頭進行拍照的實現示例

    Pyqt5打開電腦攝像頭進行拍照的實現示例

    本文介紹了如何使用Pyqt5來控制攝像頭拍照,通過構建一個簡單的用戶界面,我們可以實現從攝像頭實時獲取圖像,保存圖片,感興趣的可以了解一下
    2023-08-08
  • 一文帶你掌握Python中的深淺拷貝

    一文帶你掌握Python中的深淺拷貝

    本文將深入解析Python中的深淺拷貝問題,通過實例演示賦值,淺拷貝和深拷貝的區(qū)別,這篇文章剖析了字典.copy()方法的誤區(qū),并給出最佳實踐建議,希望對大家有所幫助
    2026-01-01
  • tensorflow使用指定gpu的方法

    tensorflow使用指定gpu的方法

    TensorFlow是一個基于數據流編程(dataflow programming)的符號數學系統(tǒng),被廣泛應用于各類機器學習,這篇文章主要介紹了tensorflow使用指定gpu的方法,需要的朋友可以參考下
    2020-02-02
  • 基于Python打造一個媒體管理播放器

    基于Python打造一個媒體管理播放器

    在日常生活中,我們經常需要管理和播放大量媒體文件,這篇文章主要介紹了如何使用Python自己打造一個簡單又強大的媒體管理播放器,希望對大家有所幫助
    2024-11-11
  • pandas使用apply多列生成一列數據的實例

    pandas使用apply多列生成一列數據的實例

    今天小編就為大家分享一篇pandas使用apply多列生成一列數據的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • Python 利用base64庫 解碼本地txt文本字符串

    Python 利用base64庫 解碼本地txt文本字符串

    這篇文章主要介紹了Python 利用base64庫 解碼本地txt文本字符串的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 使用Python快速搭建HTTP服務和文件共享服務的實例講解

    使用Python快速搭建HTTP服務和文件共享服務的實例講解

    今天小編就為大家分享一篇使用Python快速搭建HTTP服務和文件共享服務的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • 使用scrapy實現爬網站例子和實現網絡爬蟲(蜘蛛)的步驟

    使用scrapy實現爬網站例子和實現網絡爬蟲(蜘蛛)的步驟

    本文分二個示例,第一個是個簡單的爬網站的小例子,第二個例子實現目是從一個網站的列表頁抓取文章列表,然后存入數據庫中,數據庫包括文章標題、鏈接、時間,大家參考使用吧
    2014-01-01

最新評論

泾源县| 台南县| 长阳| 鹤山市| 南康市| 永兴县| 昌图县| 岢岚县| 仪陇县| 定兴县| 阿拉尔市| 丹巴县| 斗六市| 乌拉特后旗| 武平县| 乳源| 辽阳市| 当阳市| 兴国县| 乌拉特后旗| 临泽县| 永顺县| 西峡县| 吴堡县| 中宁县| 建瓯市| 太白县| 古丈县| 天峻县| 双城市| 仪陇县| 会宁县| 绥江县| 黎平县| 铁岭县| 吉安县| 唐河县| SHOW| 柘荣县| 丰县| 宜州市|