أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

CSV كبير بيكسر RAM؟ chunksize في pandas يحلها بهدوء

📅 ٢٥ أبريل ٢٠٢٦⏱ 4 دقائق قراءة
CSV كبير بيكسر RAM؟ chunksize في pandas يحلها بهدوء

CSV كبير بيكسر RAM؟ chunksize في pandas يحلها بهدوء

لو سكربت Python بيقع كل ما تقرأ ملف CSV كبير، هتعرف هنا طريقة تخفض Peak RAM من حوالي 7.8GB إلى أقل من 1.3GB بدون تغيير كامل في البايبلاين.

مستوى القارئ: متوسط

المشكلة باختصار

الطريقة الشائعة هي إنك تعمل pd.read_csv("events.csv") وخلاص. الطريقة دي بتفشل لما حجم الملف يقرب من RAM المتاحة، لأن pandas لا يقرأ النص الخام فقط. هو يحوّل الأعمدة لأنواع بيانات، يبني index، ويتعامل مع missing values. فملف 8GB ممكن يستهلك 12GB أو أكثر أثناء التحويل.

الافتراض إن عندك Job يومي بيقرأ events أو orders من نظام خارجي، وحجم الملف بين 2GB و10GB. لو عندك موقع بـ 50K زائر في اليوم، ملف الأحداث الشهري ممكن يكبر بسرعة، وساعتها المشكلة مش في سرعة CPU فقط. المشكلة إن الذاكرة بتنفد قبل ما الحساب يبدأ أصلاً.

رسم بياني يقارن استهلاك RAM وزمن التشغيل بين قراءة CSV كامل ومعالجته بدفعات chunksize في pandas

مثال بسيط قبل التعريف العلمي

ركز في المثال ده: بدل ما تنقل 1000 صندوق مرة واحدة وتكسر العربية، انقل 50 صندوق في كل مشوار. هتعمل مشاوير أكثر، لكن العربية مش هتقف. ده بالظبط اللي بيعمله chunksize.

علميًا، pandas.read_csv(..., chunksize=N) لا يرجع DataFrame واحد. بيرجع iterator يطلع DataFrame صغير في كل مرة. كل دفعة تتعالج، تتجمع نتيجتها، وبعدها تسيب الذاكرة للدفعة التالية. المكسب: Peak RAM أقل بكثير. التكلفة: الكود أطول، وبعض العمليات اللي تحتاج الملف كله مرة واحدة لازم تتعاد صياغتها.

الحل العملي: عالج الملف على دفعات

المثال التالي يحسب إجمالي المبيعات لكل دولة من ملف كبير، بدون تحميل الملف كله في الذاكرة. استخدمه كبداية، وبعدها بدّل أسماء الأعمدة حسب ملفك.

Python
import pandas as pd

input_path = "orders.csv"
output_path = "sales_by_country.csv"

partial_results = []

for chunk in pd.read_csv(
    input_path,
    chunksize=100_000,
    usecols=["country", "total", "status"],
    dtype={"country": "category", "total": "float64", "status": "category"},
):
    paid = chunk[chunk["status"] == "paid"]
    summary = paid.groupby("country", observed=True)["total"].sum()
    partial_results.append(summary)

final = pd.concat(partial_results, axis=1).fillna(0).sum(axis=1)
final.sort_values(ascending=False).to_csv(output_path, header=["total_sales"])
print(f"saved: {output_path}")

لو جرّبت ده على ملف 8GB، التوقع الواقعي إن الذاكرة القصوى تبقى بين 900MB و1.3GB مع chunksize=100_000. في المقابل، زمن التشغيل ممكن يزيد من 14 دقيقة إلى 16 أو 18 دقيقة. الـ trade-off هنا واضح: بتكسب استقرار وRAM أقل، وبتخسر شوية زمن وكود أبسط.

مخطط يوضح مسار CSV كبير إلى read_csv chunksize ثم تنظيف وتجميع كل دفعة قبل إخراج ملف صغير

3 تحسينات صغيرة بتفرق

  1. استخدم usecols. لو محتاج 3 أعمدة من 40 عمود، اقرأ 3 فقط. ده يقلل الذاكرة والوقت معًا.
  2. حدد dtype. بدل ما pandas يخمّن نوع كل عمود في كل دفعة، قل له النوع المتوقع. ده يقلل surprises في الإنتاج.
  3. اجمع نتائج صغيرة. لا تخزن كل chunk في list كـ DataFrame كامل. خزن summary صغير فقط، زي مجموع أو count أو average.

أفضل طريقة للقياس إنك تشغل النسختين على نفس الملف ونفس الجهاز. استخدم أمر النظام لمراقبة الذاكرة، أو سجّل الزمن من داخل Python. لا تحكم من تشغيل واحد. شغّل مرتين أو ثلاثة وخد المتوسط.

Bash
/usr/bin/time -v python process_orders.py
# راقب: Maximum resident set size و Elapsed time

متى لا تستخدم هذه الطريقة

لا تستخدم chunksize لو التحليل يحتاج ترتيبًا عالميًا للملف كله، مثل sort كامل على 200 مليون صف، إلا لو عندك خوارزمية external sort. ولا تستخدمها لو الملف صغير، مثل 100MB، لأن التعقيد الإضافي مش مستاهل. ولو البايبلاين بتاعك صار يعتمد على joins معقدة وتحويلات كثيرة، فكر في DuckDB أو Polars أو تحويل CSV إلى Parquet بدل ترقيع القراءة فقط.

مصادر اعتمدت عليها

  • توثيق pandas.read_csv لخيارات chunksize وusecols وdtype.
  • دليل pandas للتعامل مع البيانات الأكبر من الذاكرة.
  • توثيق Python time لو هتقيس زمن التشغيل من داخل السكربت.

الخطوة التالية

افتح أبطأ سكربت CSV عندك، وضيف usecols وchunksize=100_000 في أول تجربة. لو الذاكرة نزلت والزمن زاد أقل من 25%، خليه هو المسار الافتراضي للإنتاج.

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة