pandas 太慢、內存不夠怎麼辦提示詞(向量化改寫、dtype 優化、分塊讀取、何時換 Polars 或 DuckDB)

用 pandas 處理幾百萬行數據時腳本跑半小時、或者直接內存溢出時用:把代碼和數據規模給 AI,它先找出最慢的環節,再把逐行循環和 apply 改寫成向量化操作,優化數據類型與讀取方式,必要時給出用 Polars 或 DuckDB 改寫的版本。

NNathaniel bigo··原創首發·AI 輔助撰寫
通用大模型 對話模型通用
你是一名擅長數據處理性能優化的工程師。請幫我優化下面的 pandas 代碼。

- 數據規模:[數據規模](例:CSV 文件 3GB,約 2000 萬行,30 列)
- 機器配置:[機器配置](例:筆記本,16G 內存)
- 當前耗時或報錯:[當前情況](例:跑 40 分鐘,或讀取時內存溢出)
- 代碼:
  [粘貼代碼]
- 最終需要的結果:[最終結果](例:按用戶彙總的一張小表)

請按以下順序分析:
1. 定位瓶頸:給出測量每一步耗時與內存佔用的方法,先找到最慢的那一步,而不是憑感覺優化。
2. 讀取階段:
   - 只讀取需要的列;
   - 指定合適的數據類型(低基數的文本列用分類類型、整數用更小的位寬、日期在讀取時解析);
   - 數據大於內存時分塊讀取並逐塊聚合;
   - 文件反覆讀取時,轉換為列式存儲格式(如 Parquet)。
3. 計算階段:
   - 把逐行循環、對行使用的 apply 改寫為向量化運算;
   - 條件賦值用向量化的條件選擇函數,而不是逐行判斷;
   - 字符串處理使用字符串訪問器的方法;
   - 避免在循環中不斷拼接數據框,先收集再一次性合併;
   - 儘早過濾和聚合,減少後續處理的數據量。
4. 對每一處改寫,說明預計的提升來源,並保證結果與原代碼一致(給出核對代碼)。
5. 換工具的判斷:如果優化後仍然不夠,給出用 Polars(惰性模式)或 DuckDB(直接對文件執行 SQL)實現同樣邏輯的代碼,並說明兩者各自適合的情況。

不要為了性能犧牲正確性;對結果有影響的改動(例如類型降級可能導致的溢出或精度損失)要明確提示。

高亮處換成你自己的內容:[數據規模]、[機器配置]、[當前情況]、[粘貼代碼]、[最終結果]

ChatGPT Plus 充值

已被複製 0 次

使用說明

怎麼填變量:[數據規模] 和 [機器配置] 決定方案:數據能放進內存時,向量化和類型優化往往就夠了;數據明顯超過內存時,要麼分塊,要麼直接換成 DuckDB 這類不需要把全部數據載入內存的工具。[最終需要的結果] 很重要,如果最後只要一張彙總表,很多中間步驟可以直接在讀取時完成。

常見坑:

  • 用 iterrows 逐行處理幾百萬行,是 pandas 最常見的性能問題。絕大多數逐行邏輯都可以改寫成整列運算。
  • 文本列預設是對象類型,非常佔內存。像「省份」「狀態」這類取值很少的列,轉換為分類類型可以大幅減少內存。
  • 把整數降為更小的位寬來省內存時,沒檢查最大值,導致數值溢出。降級前先看取值範圍。

追問技巧:優化後追問「把這個流程改成每天自動跑的腳本,只處理新增的數據」。

示例輸出

示例,僅供參考(節選)

瓶頸:第 12 行用 apply 逐行計算會員等級,佔總耗時的約 80%(需你用計時代碼確認)。

python
import numpy as np
import pandas as pd

# 讀取:只取需要的列,並指定類型
df = pd.read_csv("orders.csv", usecols=["user_id", "amount", "province", "created_at"],
                 dtype={"user_id": "int64", "province": "category"}, parse_dates=["created_at"])

# 改寫前:df["level"] = df.apply(lambda r: "高" if r.amount > 1000 else ("中" if r.amount > 200 else "低"), axis=1)
# 改寫後:向量化的條件選擇
df["level"] = np.select([df["amount"] > 1000, df["amount"] > 200], ["高", "中"], default="低")

數據超過內存時,用 DuckDB 直接對文件執行 SQL:

python
import duckdb
result = duckdb.sql("""
    SELECT user_id, SUM(amount) AS total
    FROM read_csv_auto('orders.csv')
    GROUP BY user_id
""").df()

同款作品

用這條提示詞做出來的作品;原作者會因此獲得積分

做同款

還沒有同款,來做第一個。

Nathaniel 的更多內容

同主題

同模型

0 條評論

登入 後參與評論

還沒有評論,來搶沙發~