الوحدة 5 · الإجابة عن أسئلة حقيقية
التحليل القابل لإعادة الإنتاج
18 دقراءة 3 دتمرين Python
الدرس في لمحة
حوّل تحليلًا لمرة واحدة إلى تحليل قابل لإعادة الإنتاج باستخدام المُعامِلات والدوال والـ assertions والمخرجات المحفوظة و notebook نظيف يعمل من الأعلى إلى الأسفل، واعرف إلى أين تتجه بعد هذه الدورة.
لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.
إجابة الربع الرابع مكتوبة. بعد ثلاثة أشهر سيسأل رئيس النمو السؤال نفسه عن الربع الأول، وقد يكون من يجيب أنت، أو زميل، أو أنت وقد نسيت كل التفاصيل. التحليل الذي لا يعمل إلا في الـ notebook الذي وُلد فيه عمل لمرة واحدة. أما التحليل الذي يستطيع أيّ شخص إعادة تشغيله من الملفات الخام والحصول على الأرقام نفسها فهو أصل ذو قيمة. والفرق حفنة من العادات.
شكل التحليل القابل لإعادة التشغيل
import pandas as pd
# Parameters: everything that changes between runs lives here.
ORDERS_FILE = "orders.csv"
ITEMS_FILE = "order_items.csv"
QUARTER = "2025Q4"
EXCLUDE_STATUSES = ["cancelled"]
def load_orders(orders_file, items_file):
"""One row per order with revenue (after discounts, no shipping)."""
items = pd.read_csv(items_file)
orders = pd.read_csv(orders_file, parse_dates=["order_date"])
items["revenue"] = items["quantity"] * items["unit_price"] * (1 - items["discount"])
revenue = items.groupby("order_id", as_index=False)["revenue"].sum()
df = orders.merge(revenue, on="order_id", how="left", validate="one_to_one")
assert df["order_id"].is_unique, "duplicate orders"
assert df["revenue"].notna().all(), "orders without items"
return df
def quarter_summary(df, quarter, exclude):
kept = df[~df["status"].isin(exclude)]
in_q = kept[kept["order_date"].dt.to_period("Q") == quarter]
assert len(in_q) > 0, f"no orders in {quarter}"
return {
"quarter": quarter,
"revenue": round(in_q["revenue"].sum(), 2),
"orders": len(in_q),
"customers": in_q["customer_id"].nunique(),
"aov": round(in_q["revenue"].mean(), 2),
}
df = load_orders(ORDERS_FILE, ITEMS_FILE)
summary = pd.DataFrame([quarter_summary(df, q, EXCLUDE_STATUSES) for q in ["2025Q3", QUARTER]])
print(summary)
print(f"pandas {pd.__version__}")أربع أفكار تحمل هذا الكود. المُعامِلات (parameters) في الأعلى تسمّي كل مُدخل وكل قرار، ومنها تعريف الإيراد، فيغيّر تشغيل الربع القادم سطرًا واحدًا. والدوال تحمل الخطوات، وتأخذ مُدخلاتها كوسائط وتعيد النتائج، فلا تعتمد أبدًا على متغيّر متبقٍّ من مكان آخر. والـ assertions تحدّد ما يجب أن يكون صحيحًا في البيانات قبل حساب أي شيء منها، كما فعلت في الدرس 3.5. وطباعة الإصدار تسجّل أيّ إصدار من pandas أنتج الأرقام، لأن القيم الافتراضية تتغيّر فعلًا بين الإصدارات الرئيسية.
نظافة الـ notebook
الـ notebooks ممتازة للاستكشاف وخطيرة لإعداد التقارير، لأن الخلايا يمكن أن تُشغَّل بأي ترتيب، والمتغيّرات تبقى بعد زوال الخلايا التي صنعتها. قبل أن تشارك واحدًا:
- شغّل Restart and Run All. إذا فشل أو تغيّرت الأرقام، فقد كان الـ notebook يعتمد على حالة مخفية.
- اقرأ الملفات ولا تعدّلها أبدًا. احتفظ بالملفات المُصدَّرة الخام كما هي في مجلد
data/raw؛ التنظيف يحدث في الكود، فيمكن تكراره. - انقل الكود القابل لإعادة الاستخدام إلى الخارج. حين يحتاج اثنان من الـ notebooks إلى
clean_orders، فمكانها ملف.pyتستورده. - اكتب المخرجات في ملفات. تنتج
summary.to_csv("q4_summary.csv", index=False)الأرقام التي تستخدمها الشريحة؛ والنسخ من الشاشة يفتح الباب للأخطاء الكتابية. - اكتب التعريف بجانب الرقم. خلية Markdown قصيرة تقول ما الذي يشمله “الإيراد” توفّر عليك جدالًا لاحقًا.
ما تستطيع فعله الآن
بدأت هذه الدورة وأنت لا تستطيع كتابة سطر Python واحد. أنت الآن تستطيع تحميل أي ملف CSV وفحصه، وتنظيف فوضى العالم الحقيقي (الخانات الفارغة، والأخطاء الكتابية، والمبالغ المكتوبة كنصوص، والتواريخ الملتبسة، والمكرّرات)، وربط الجداول وإعادة تشكيلها، وتلخيصها بحسب المجموعة وعبر الزمن، ووصف التوزيعات بصدق، وتحويل كل ذلك إلى إجابة مدعومة بالأدلة والتحفّظات. هذا هو العمل اليومي لمحلل البيانات.
أين تتجه بعد ذلك يعتمد على الأسئلة التي تريد الإجابة عنها. تستخدم دورة SQL للمحلّلين بيانات Cartwheel نفسها داخل قاعدة بيانات، وهناك توجد معظم بيانات الشركات فعلًا. وتلتقط الدورة المكثّفة في تعلّم الآلة الملف churn.csv وتطرح السؤال التالي: أيّ العملاء على وشك الرحيل؟ أيًّا كان اختيارك، احتفظ بعادات هذه الدورة: افحص قبل أن تثق، واكتب التعريف، واجعل عملك قابلًا لإعادة التشغيل.
أهم النقاط
- التحليل القابل لإعادة الإنتاج (reproducible) يعطي النتيجة نفسها حين يشغّله شخص آخر من الملفات الخام، من الأعلى إلى الأسفل، دون خطوات يدوية.
- ضع المُدخلات والاختيارات في مُعامِلات مسمّاة في الأعلى (مسارات الملفات، والربع، وتعريف الإيراد)، كي تعني إعادة التشغيل لفترة جديدة تغيير سطر واحد.
- الدوال تحمل الخطوات التي تكرّرها؛ والـ assertions تحدّد ما يجب أن تبدو عليه البيانات قبل الثقة بالنتائج.
- استخدم Restart and Run All قبل مشاركة أي notebook، واحفظ النتائج بـ
to_csv(..., index=False)بدلًا من نسخ الأرقام بيدك.