برمجة بايثونتحليل البيانات الإحصائيعلوم البيانات

كيفية حساب المتوسط الشرطي في بانداز (مع أمثلة)

دليل أكاديمي شامل يشرح كيفية حساب المتوسط الشرطي في مكتبة Pandas باستخدام لغة بايثون، مع تطبيقات وأمثلة عملية متقدمة لتحليل البيانات بكفاءة.

تاريخ النشر

تُعد عملية استخلاص المقاييس الإحصائية الموجهة أحد الأركان الجوهرية في هندسة البيانات والتحليل الاستكشافي المتقدم؛ إذ لا تقتصر معالجة البيانات الحديثة على حساب المقاييس الوصفية العامة فحسب، بل تمتد لتشمل تفكيك الظواهر المعقدة عبر تجزئة البيانات إلى طبقات وشرائح فرعية تخضع لقيود وشروط محددة. يمثل المتوسط الحسابي الشرطي (Conditional Mean) حجر الزاوية في هذه المنهجية، حيث ينقل المحلل من فضاء النظرة الشمولية السطحية إلى فضاء الاستدلال الموجه الذي يعكس السلوك الفعلي للأنظمة والقطاعات المدروسة تحت ظروف تشغيلية وبيئية متباينة.

تتربع مكتبة Pandas مفتوحة المصدر في لغة بايثون على عرش الأدوات البرمجية المستخدمة لتحقيق هذه الأغراض الإحصائية، لما تمتلكه من بنية تحتية متطورة تدمج بين مرونة لغات البرمجة عالية المستوى والسرعة الفائقة الناتجة عن المعالجة المتجهية (Vectorized Processing) المكتوبة بلغة C عبر مكتبة NumPy. إن فهم كيفية تطويع هذه الأداة لحساب المتوسطات المشروطة بدقة متناهية وبكفاءة حسابية عليا ليس مجرد مهارة برمجية روتينية، بل هو ضرورة منهجية لكل عالم بيانات ومهندس ذكاء اصطناعي يسعى لبناء نماذج تنبؤية متزنة وموثوقة.

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

1. مقدمة عامة إلى مفهوم المتوسط الشرطي وأهميته الإحصائية في مكتبة Pandas

1.1 التعريف الرياضي والإحصائي للمتوسط الحسابي الشرطي (Conditional Mean)

يمثل المتوسط الحسابي البسيط لمجموعة بيانات ذات حجم $N$ مجموع القيم مقسوماً على عددها الإجمالي، وهو مقياس يعبر عن النزعة المركزية للبيانات دون النظر إلى التباينات الهيكلية الكامنة في المجتمع الإحصائي. في المقابل، يُعرَّف المتوسط الحسابي الشرطي في نظرية الاحتمالات والإحصاء الرياضي بأنه القيمة المتوقعة لمتغير عشوائي $Y$ عند ثبوت أو تحقق شرط معين يفرضه متغير آخر $X$، ويُرمز له رياضياً بالصيغة:

$$\mathbb{E}[Y mid X = x] = \int_{-\infty}^{\infty} y \cdot f_{Y|X}(y mid x) , dy$$

في حالة المتغيرات المتصلة، أو بالصيغة المتقطعة عبر جمع حاصل ضرب القيم في احتمالاتها الشرطية المقابلة:

$$\mathbb{E}[Y mid X = x] = \sum_{y} y \cdot P(Y = y mid X = x)$$

يكمن الفرق الجوهري بين المقياسين في أن المتوسط العام يفترض تجانس المجتمع وتطابق التوزيع الاحتمالي لجميع المشاهدات، مما قد يؤدي إلى استنتاجات مضللة في حال وجود استقطاب أو توزيعات متعددة الأنماط (Multimodal Distributions). أما المتوسط الشرطي فيعمل على تقييد فضاء العينة بفضاء جزئي يحقق سمة محددة، مما يتيح للباحث عزل أثر المتغيرات الوسيطة والمشوشة (Confounding Variables) واستكشاف العلاقات السببية والارتباطية بدقة متناهية.

تتجلى أهمية الاستدلال الإحصائي الشرطي عند دراسة السلاسل الزمنية والبيانات المقطعية المعقدة؛ إذ يتيح التحقق من فرضيات دقيقة تتعلق بسلوك المتغير التابع تحت مستويات مختلفة من المتغيرات المستقلة، وهو ما يشكل الأساس النظري لنماذج الانحدار الخطي (Linear Regression) التي تفترض أن دالة الانحدار ما هي إلا تقدير للمتوسط الشرطي لـ $Y$ بمعلومية مصفوفة المدخلات $X$.

1.2 دور مكتبة Pandas في تسهيل العمليات الإحصائية المشروطة

تعتمد مكتبة Pandas على هيكلين رئيسيين للبيانات هما سلاسل السلاسل أحادية البعد (Series) وجداول البيانات ثنائية الأبعاد (DataFrame). تم تصميم هذه الهياكل لتوفير تكامل عالي المستوى بين الفهرسة المكانية والفهرسة التسموية، مما يمنح المطورين القدرة على استهداف أجزاء محددة من الذاكرة وتطبيق العمليات الإحصائية عليها مباشرة دون الحاجة إلى اللجوء للحلقات التكرارية التقليدية في بايثون.

تعتمد الكفاءة التشغيلية لمكتبة Pandas على مفهوم “المعالجة الموجهة” (Vectorized Operations)، حيث تُنفَّذ العمليات الحسابية والمنطقية مباشرة على مستوى شرائح الذاكرة المتجاورة المكتوبة بلغة C، عبر الاستفادة من تعليمات وحدة المعالجة المركزية الحديثة من نوع SIMD (Single Instruction, Multiple Data). يتيح هذا التصميم المعماري تقليص الزمن الحسابي اللازم لمقارنة ملايين الصفوف وتصفيتها ثم حساب متوسطاتها من عدة دقائق إلى بضعة أجزاء من الألف من الثانية.

يتكامل هذا النظام البرمجي بسلاسة مع المنظومة التحليلية الشاملة في لغة بايثون، بما في ذلك حزم الحوسبة العلمية مثل SciPy وحزم النمذجة الإحصائية مثل Statsmodels وأطر التعلم الآلي مثل Scikit-Learn. توفر Pandas واجهات برمجية متناسقة تسمح بتمرير نتائج المتوسطات الشرطية مباشرة إلى خوارزميات التدريب أو دوال التمثيل البياني، مما يقلل من الفاقد الإجرائي في نقل وتحويل البيانات بين البيئات المختلفة.

1.3 الأهمية العملية لحساب المتوسط الشرطي في علوم البيانات وتطبيقاتها

يمثل حساب المتوسط الشرطي في المشاريع التطبيقية لعلوم البيانات خطوة مفصلية في مرحلة التحليل الاستكشافي للبيانات (Exploratory Data Analysis – EDA)؛ حيث يتيح للخبراء استخراج المؤشرات التشغيلية الحيوية للقطاعات المختلفة بشكل فوري، مثل مقارنة متوسط حجم المبيعات لكل منطقة جغرافية، أو قياس متوسط زمن الاستجابة للنظم الرقمية تحت مستويات الحمل المرتفعة، أو تحديد متوسط كفاءة استهلاك الوقود للمركبات ذات المحركات الهجينة مقارنة بالتقليدية.

يلعب المتوسط الشرطي دوراً استراتيجياً في مرحلة “هندسة الميزات” (Feature Engineering) الخاصة بنماذج التعلم الآلي؛ حيث يُستخدم على نطاق واسع في تقنيات “الترميز بالهدف” (Target Encoding أو Mean Encoding)، والتي تتضمن استبدال القيم الفئوية في المتغيرات النصية بالمتوسط الشرطي للمتغير التابع المقترن بتلك الفئة. تؤدي هذه الخطوة إلى تحسين القدرة التنبؤية للنماذج المعقدة مثل خوارزميات تعزيز التدرج (Gradient Boosting) والشبكات العصبية العميقة، شريطة تطبيقها بأساليب تمنع تسريب البيانات (Data Leakage).

تعتمد أنظمة كشف الاحتيال والمراقبة البيئية والمالية على المتوسطات المشروطة لتحديد القيم الشاذة والمتطرفة (Outliers)؛ إذ إن تصنيف نقطة بيانات بأنها شاذة مقارنة بالمتوسط العام للمجتمع قد يكون خاطئاً، بينما مقارنتها بالمتوسط الشرطي للقطاع أو السياق الزمني الذي تنتمي إليه يكشف الانحرافات الدقيقة غير الطبيعية بدقة بالغة.

2. البنية الأساسية لحساب المتوسط الشرطي باستخدام دالة loc

2.1 تشريح بناء الجملة البرمجية (Syntax Breakdown) لـ df.loc

تُعد خاصية الفهرسة df.loc الأداة المعيارية والأكثر قوة في Pandas للوصول إلى مجموعات فرعية من البيانات بناءً على التسميات الفهرسية أو المصفوفات البوليانية المنطقية. يتألف بناء الجملة البرمجية لهذه الدالة من معاملين رئيسيين يوضعان داخل قوسي الفهرسة المربعة ويفصل بينهما فاصلة عادية: df.loc[row_indexer, column_indexer].

يتحكم المعامل الأول (Row Indexer) في تحديد الصفوف المستهدفة بالتحليل؛ وعند حساب المتوسط الشرطي، يُمرَّر إلى هذا المعامل مصفوفة شرطية بوليانية (Boolean Mask) تقوم باختبار خاصية معينة في كل صف وتنتج قيماً منطقية (True أو False). بينما يتحكم المعامل الثاني (Column Indexer) في اختيار العمود أو مجموعة الأعمدة المراد حساب المقياس الإحصائي لها، مما يضمن تقليص حجم المصفوفة المرجعة في الذاكرة لتقتصر حصراً على القيم المطلوبة.

بمجرد تطبيق الفهرسة واقتصار النطاق على القيم المتوافقة مع الشرط والعمود المحدد، يُربط التعبير مباشرة بالدالة الإحصائية .mean()؛ لتقوم باختزال السلسلة الناتجة إلى قيمة عددية مفردة تمثل المتوسط الحسابي المشروط لتلك الشريحة المستهدفة، وفق التركيب البرمجي النموذجي: df.loc[df['condition_column'] == value, 'target_column'].mean().

2.2 ميكانيكية الفهرسة المنطقية (Boolean Indexing) داخلياً

لفهم الآلية الداخلية لتنفيذ العمليات الشرطية، يجب تتبع كيفية تعامل محرك Pandas مع التعبيرات المنطقية على مستوى الذاكرة. عندما يُكتب تعبير منطقي مثل df['team'] == 'A'، تقوم مكتبة Pandas باستدعاء المشغل الداخلي للمساواة الموجهة على الكائن السلسلي Series، مما يولد سلسلة جديدة بالكامل تحتوي على نوع بيانات بولياني (dtype: bool)، تماثل بطولها وفهرسها الإطار الأصلي.

عند تمرير هذا القناع البولياني إلى خاصية .loc[]، يقوم المحرك الداخلي بتحديد العناوين النسبية في الذاكرة (Memory Offsets) لجميع العناصر المقابلة للقيمة True حصراً، وتجاهل العناصر ذات القيمة False تماماً. لا تقوم هذه العملية بنسخ البيانات فوراً في كافة الحالات، بل قد تعيد “عرضاً” (View) مقيداً للذاكرة الأصلية أو نسخة سطحية (Shallow Copy) اعتماداً على بنية البيانات وتجانس الأنواع في الأعمدة، مما يحافظ على كفاءة استهلاك الذاكرة العشوائية (RAM).

تنتقل الشريحة المصفاة الناتجة بعد ذلك إلى روتين حساب المتوسط التابع لمكتبة NumPy الأساسية والمكتوب بلغة C، حيث يُنفذ الجمع التراكمي لعناصر المصفوفة المتجاورة عبر مكدس الذاكرة، ثم يُقسم المجموع الناتج على عدد العناصر الصالحة المشتقة من تعداد القيم المحققة للشرط، مع الأخذ بالاعتبار التعامل الديناميكي مع القيم المفقودة.

2.3 مثال توضيحي أساسي: الحساب البسيط على عينة بيانات

لتجسيد هذه المفاهيم في سياق عملي تطبيقي، نفترض وجود إطار بيانات يمثل أداء مجموعة من لاعبي كرة السلة في فرق مختلفة، حيث يحتوي الإطار على أربعة أعمدة رئيسية هي: اسم الفريق (team)، وعدد النقاط المسجلة (points)، والتمريرات الحاسمة (assists)، وعدد مرات الاستحواذ (rebounds). يتضمن الإطار صفوفاً تمثل اللاعبين موزعين على الفرق ‘A’ و ‘B’ و ‘C’ مع تباين في مستويات الأداء الرقمي.

لحساب متوسط النقاط المسجلة للاعبي الفريق ‘A’ فقط، نكتب التعبير البرمجي الآتي:

mean_points_A = df.loc[df['team'] == 'A', 'points'].mean()

عند تنفيذ هذا الكود خطوة بخطوة، تقوم المكتبة أولاً بمقارنة كل عنصر في عمود ‘team’ بالقيمة النصية ‘A’ لإنتاج مصفوفة بوليانية. ثانياً، يقوم .loc باستخدام هذه المصفوفة لاستخلاص قيم عمود ‘points’ المقابلة للقيم المنطقية الصائبة فقط، متجاهلاً بقية الفرق. ثالثاً، تُستدعى الدالة .mean() لتجمع هذه النقاط المستخلصة وتقسمها على عدد لاعبي الفريق ‘A’. يمكن التحقق يدوياً من صحة الناتج عن طريق تصفية الجدول يدوياً وجمع القيم المختارة وقسمتها على عددها للتأكد من تطابق المخرجات البرمجية مع الحساب الإحصائي النظري.

3. حساب المتوسط الشرطي بناءً على المتغيرات الفئوية (Categorical Variables)

3.1 تطبيق الشروط على القيم النصية الفردية

يعد تطبيق الشروط على المتغيرات الفئوية النصية أحد أكثر الأنماط شيوعاً في المعالجة البيانية. عند استخدام عامل المساواة المزدوج (==)، يتم التحقق من التطابق التام بين السلسلة النصية المخزنة في خلايا العمود والقيمة المعيارية المحددة في الشرط. ومع ذلك، تتطلب هذه العملية حذراً شديداً نظراً لحساسية النصوص لحالة الأحرف (Case Sensitivity) في اللغات اللاتينية، بالإضافة إلى التأثير السلبي للمسافات الفارغة البادئة أو اللاحقة (Trailing/Leading Whitespaces) التي قد تؤدي إلى فشل التطابق رغم التشابه الظاهري للكلمات.

لتفادي هذه المشكلات الشائعة، يُنصح بتطبيق عمليات المعالجة المسبقة للنصوص قبل صياغة الشروط الإحصائية، مثل استخدام التابع str.strip() لإزالة الفراغات غير المرئية وتوحيد حالة الأحرف باستخدام str.lower() أو str.upper()، مما يضمن أن الشرط يغطي كافة المشاهدات المستهدفة دون إسقاط أي منها نتيجة أخطاء الإدخال.

من منظور الأداء، تختلف كفاءة المقارنة النصية اختلافاً جذرياً بناءً على نوع البيانات المخصص للعمود (Dtype)؛ فعند تخزين النصوص ككائنات عامة (object)، تتطلب عملية المقارنة فحص مؤشرات الذاكرة المتفرقة لسلاسل بايثون الفردية. بينما يؤدي تحويل العمود مسبقاً إلى النوع الفئوي (category) إلى تحويل النصوص داخلياً إلى رموز صحيحة (Integer Codes)، مما يجعل عمليات المقارنة المنطقية فائقة السرعة نظراً لتنفيذها على أرقام صحيحة مباشرة على مستوى المسجلات الحسابية للمعالج.

3.2 استخدام دالة isin() لتضمين فئات متعددة في الشرط

تنشأ في كثير من الأحيان الحاجة إلى حساب المتوسط لمجموعة بيانات تجمع بين عدة فئات تصنيفية معاً، مثل حساب متوسط نقاط اللاعبين المنتمين إلى الفريقين ‘A’ و ‘B’ مجتمعين، واستبعاد الفريق ‘C’. توفر مكتبة Pandas الدالة الموجهة isin() كحل نموذجي ومحسن برمجياً لهذه الحالات، حيث تقبل الدالة قائمة أو مجموعة أو مصفوفة من القيم المستهدفة وتبحث عن وجود عناصر العمود ضمنها.

تُصاغ هذه العملية بالكود التالي: df.loc[df['team'].isin(['A', 'B']), 'points'].mean(). يتميز هذا الأسلوب بأنه يختزل كتابة الشروط المنطقية الطويلة، فبدلاً من استخدام روابط الفصل المتعددة التي تزيد من تعقيد الكود وعرضته للخطأ، تقوم isin() بإنشاء القناع البولياني بكفاءة خوارزمية عالية تعتمد على هياكل جداول التجزئة (Hash Tables) السريعة عند البحث داخل المجموعات الكبيرة.

تتفوق دالة isin() بشكل ملحوظ على التعبيرات المنطقية المتكررة مثل (df['team'] == 'A') | (df['team'] == 'B') من حيث وضوح البنية البرمجية وقابلية الصيانة، كما تتيح تمرير متغيرات تحتوي على قوائم الفئات ديناميكياً من واجهات المستخدم أو ملفات الإعداد الخارجية دون الحاجة لإعادة كتابة التعبير المنطقي في الكود المصدر.

3.3 تطبيق الشروط بناءً على تطابق الأنماط النصية (String Matching)

لا تكون الفئات النصية دائماً محددة بقيم ثابتة ومطابقة تماماً، بل قد تتطلب المعالجة استخلاص البيانات بناءً على احتواء النصوص على مقاطع جزئية معينة أو تطابقها مع نمط نصي محدد. تتيح حزمة الدوال النصية المدمجة في Pandas، والمتاحة عبر الموجه str، تطبيق شروط معقدة مثل str.contains() للبحث عن كلمة فرعية، أو str.startswith() و str.endswith() للتحقق من بدايات ونهايات النصوص.

يتيح التابع str.contains() استخدام التعابير النمطية (Regular Expressions – Regex) فائقة المرونة؛ فعلى سبيل المثال، يمكن حساب متوسط النقاط لجميع الفرق التي تبدأ أسماؤها بحرف ‘A’ أو ‘B’ باستخدام التعبير: df.loc[df['team'].str.contains('^[AB]', regex=True, na=False), 'points'].mean().

يعد المعامل na=False في الدوال النصية عنصراً بالغ الأهمية لا غنى عنه في المعالجة البرمجية الصارمة؛ إذ إن وجود قيم مفقودة (NaN) في العمود النصي سيؤدي افتراضياً إلى إنتاج قيم مفقودة في القناع البولياني، مما يسبب أخطاء استثنائية عند محاولة الفهرسة عبر loc. يضمن ضبط هذا المعامل تحويل كل قيمة مفقودة إلى False بصورة تلقائية، مما يعزل الصفوف غير الصالحة ويحافظ على استمرارية التدفق الحسابي بأمان ودقة.

4. تطبيق الشروط المنطقية المتعددة والمركبة (Logical Operators)

4.1 الربط المنطقي الإلزامي باستخدام عامل العطف (AND / &)

يتطلب التحليل الإحصائي المتقدم في كثير من التطبيقات تطبيق شروط متزامنة ومتعددة الأبعاد لاختيار الشريحة المستهدفة بدقة. في لغة بايثون القياسية يُستخدم الرمز and للربط المنطقي القياسي بين القيم المنفردة، إلا أنه عند التعامل مع كائنات Pandas ومصفوفات NumPy يُحظر استخدامه ويجب استبداله بعامل العطف الموضعي (Bitwise AND) المتمثل بالرمز &؛ وذلك لأن المطلوب هو تطبيق عملية العطف على كل عنصر في المصفوفة بالتوازي وليس تقييم الكائن ككل.

تفرض قواعد الأولوية الرياضية في لغة بايثون تقديم معاملات المقارنة المنطقية على العوامل الموضعية، وهو ما يفرض إلزامية إحاطة كل شرط فردي بأقواس دائرية منفصلة () لضمان تسلسل التنفيذ الصحيح. وتُصاغ الجملة البرمجية لحساب متوسط نقاط لاعبي الفريق ‘A’ الذين حققوا أكثر من 30 تمريرة حاسمة بالشكل التالي:

df.loc[(df['team'] == 'A') & (df['assists'] > 30), 'points'].mean()

في الحالات التي تكون فيها مجموعة التقاطع الناتجة عن تطبيق الشرطين فارغة تماماً (أي لا يوجد أي صف يحقق كلا المعيارين في آن واحد)، فإن مصفوفة النتائج المصفاة ستكون بطول صفر. عند استدعاء الدالة .mean() على سلسلة فارغة، سترجع Pandas القيمة الخاصة NaN (Not a Number)، وهو السلوك الإحصائي القياسي لتمثيل عدم إمكانية قسمة الصفر على الصفر، مما يتطلب معالجة برمجية لاحقة لتجنب انهيار مسارات المعالجة التالية.

4.2 الربط المنطقي التخييري باستخدام عامل الفصل (OR / |)

عند الرغبة في حساب المتوسط الحسابي لشريحة تشمل المشاهدات التي تحقق واحداً على الأقل من عدة شروط مطروحة، يُستخدم عامل الفصل الموضعي (Bitwise OR) المتمثل بالرمز |. تماماً كما في عامل العطف، تظل الأقواس المحيطة بكل تعبير شرطي إلزامية لا يمكن التنازل عنها لضمان عدم حدوث أخطاء تركيبية أثناء تفسير الكود.

تُصاغ الشروط التخييرية لتشمل مثلاً اللاعبين الذين ينتمون إلى الفريق ‘A’ أو يمتلكون عدداً من التمريرات الحاسمة يتجاوز 25 تمريرة بالصيغة: df.loc[(df['team'] == 'A') | (df['assists'] > 25), 'points'].mean(). يقوم هذا التعبير بحساب المتوسط لجميع الصفوف التي ينطبق عليها أي من الشرطين أو كلاهما معاً، مع دمج المشاهدات في مجموعة واحدة متجانسة دون تكرار الصفوف المشتركة.

يعالج محرك الفهرسة المنطقية مسألة التداخل بين المجموعات تلقائياً؛ فإذا كان اللاعب ينتمي للفريق ‘A’ ولديه في الوقت ذاته أكثر من 25 تمريرة حاسمة، فإن القناع المنطقي يعطي القيمة True لمرة واحدة فقط لهذا الصف، مما يمنع احتساب بياناته مرتين في حساب المتوسط ويضمن دقة المقام الإحصائي للعملية الحسابية الإجمالية.

4.3 استخدام عامل النفي (NOT / ~) لعزل الفئات واستبعادها

يمثل عامل النفي الموضعي المتمثل برمز المدة ~ (Tilde) أداة محورية لعكس نتائج المصفوفات البوليانية؛ حيث يقوم بتحويل كافة القيم True إلى False والعكس صحيح. تبرز الفائدة القصوى لهذا العامل عند الرغبة في استبعاد فئة معينة أو مجموعة شروط معقدة وحساب المتوسط لكافة المشاهدات المتبقية في جدول البيانات.

لحساب متوسط نقاط جميع اللاعبين في الدوري باستثناء لاعبي الفريق ‘A’، يُكتب التعبير البرمجي كالتالي: df.loc[~(df['team'] == 'A'), 'points'].mean(). كما يمكن دمج عامل النفي مع الشروط المركبة المعقدة بالاعتماد على قوانين دي مورغان (De Morgan’s Laws) المنطقية، لنفي تقاطع أو اتحاد شروط متعددة بنسق برمجي مختصر ومحكم.

يُستخدم عامل النفي بكثافة في تنقية مجموعات البيانات وعزل الفئات غير المرغوبة أو المشكوك في دقتها؛ فعلى سبيل المثال، يمكن تطبيقه مع الدوال التي تفحص القيم الشاذة أو غير المنطقية لاستبعادها وحساب المتوسط النظيف للمجتمع، مما يمنح المحلل مرونة فائقة في إعادة هيكلة فضاء العينة بأسلوب إعلاني (Declarative) مباشر.

5. حساب المتوسط الشرطي بناءً على المتغيرات الكمية والعددية (Numerical Conditions)

5.1 المقارنات العددية البسيطة (أكبر من، أصغر من، المدى)

تعتمد الشروط العددية على استخدام معاملات المقارنة الرياضية المباشرة مثل > (أكبر من)، < (أصغر من)، >= (أكبر من أو يساوي)، <= (أصغر من أو يساوي)، و != (لا يساوي). تطبق هذه المعاملات على الأعمدة الرقمية لإنتاج أقنعة بوليانية تفصل البيانات بناءً على حدود قياسية ثابتة، مثل حساب متوسط نقاط اللاعبين الذين شاركوا لأكثر من 20 دقيقة في المباراة.

لتحديد نطاق عددي يقع بين حدين أدنى وأعلى، توفر Pandas دالة مدمجة ذات كفاءة عالية هي between()، والتي تقبل الحدين كمعاملات وتدعم تضمين الحدود أو استبعادها عبر المعامل inclusive. على سبيل المثال، لحساب متوسط النقاط للاعبين الذين تتراوح تمريراتهم الحاسمة بين 10 و 30 تمريرة شاملة الطرفين، يُصاغ الكود على النحو الآتي:

df.loc[df['assists'].between(10, 30, inclusive='both'), 'points'].mean()

تسهم هذه التصفية العددية في دراسة التوزيع الإحصائي للبيانات عبر الشرائح الرقمية المختلفة؛ حيث تتيح مقارنة سلوك المتغير التابع عبر الفئات الدنيا والوسطى والعليا للمتغير المستقل، مما يكشف عن العلاقات اللاخطية المحتملة والارتباطات الجزئية داخل بنية البيانات الكلية.

5.2 الشروط المعتمدة على المقاييس الإحصائية النسبية (Dynamic Statistical Thresholds)

لا تقتصر الشروط العددية على القيم الثابتة المحددة مسبقاً (Hardcoded Thresholds)، بل تمتد لتشمل الحدود الإحصائية الديناميكية التي تُحسب تلقائياً من البيانات ذاتها أثناء التشغيل. من أبرز هذه التطبيقات حساب المتوسط للمشاهدات التي تتجاوز قيمتها المتوسط العام للمجتمع، وفق الصياغة: df.loc[df['points'] > df['points'].mean(), 'points'].mean().

يمكن توسيع هذا المفهوم ليشمل المقاييس الموضعية المتقدمة مثل المئينات الإحصائية (Quantiles) ونقاط Z المعيارية (Z-Scores). لحساب متوسط نقاط النخبة الذين يقعون في أعلى 10% من توزيع التمريرات الحاسمة، نستخدم الدالة quantile() لتوليد الحد الأدنى ديناميكياً:

top_assists_threshold = df['assists'].quantile(0.90)
mean_elite = df.loc[df['assists'] >= top_assists_threshold, 'points'].mean()

تتيح هذه المقاييس الإحصائية المتحركة عزل القيم المتطرفة والشاذة بطرق منهجية رصينة؛ مثل استخدام المدى الربيعي (IQR) لاستبعاد القيم التي تقع خارج الحدود الطبيعية للبيانات، ثم حساب “المتوسط المقيد” أو “المعدل” (Trimmed Mean) الذي يقدم تقديراً إحصائياً متيناً ومقاوماً للتشوهات الناتجة عن أخطاء القياس أو الظواهر النادرة الحدوث.

5.3 الربط بين الشروط العددية والفئوية في نفس المعادلة

يمثل الدمج بين المتغيرات الفئوية والحدود العددية قمة التعقيد التحليلي في بناء الشروط المخصصة؛ حيث يتيح إجراء مقارنات تفصيلية دقيقة مثل تقييم أداء اللاعبين ذوي الفاعلية العالية ضمن فرق محددة جغرافياً أو إدارياً. يتطلب هذا النوع من الاستعلامات دقة بالغة في صياغة الأقواس المنطقية لضمان تماسك البنية المنطقية وتفادي النتائج غير المقصودة.

يوضح التعبير البرمجي الآتي كيفية دمج شرط فئوي يستهدف فرقاً محددة مع شرط عددي نسبي يرتبط بمستوى الأداء:

df.loc[(df['team'].isin(['A', 'B'])) & (df['assists'] > df['assists'].median()), 'points'].mean()

عند بناء مثل هذه المعادلات المركبة، يجب التحقق الصارم من تجانس أنواع البيانات لتفادي أخطاء عدم تطابق الأنواع (Type Mismatch)؛ كأن تتم مقارنة عمود يحتوي على أرقام مخزنة كسلاسل نصية مع قيمة عددية حقيقية، مما يفرز أخطاء استثنائية من نوع TypeError، أو يؤدي إلى سلوك منطقي خاطئ صامت لا يمكن اكتشافه إلا بالتدقيق المعمق لمخرجات التحليل.

6. حساب المتوسط الشرطي الشامل لجميع المجموعات باستخدام groupby

6.1 المفهوم النظري لآلية Split-Apply-Combine في Pandas

تعد آلية “التقسيم والتطبيق والدمج” (Split-Apply-Combine) المفهوم البنيوي الأكثر رسوخاً في معالجة البيانات المجدولة؛ وهو النمط المعماري الذي صاغه هادلي ويكهام وجرى تنفيذه بكفاءة قصوى داخل مكتبة Pandas عبر دالة groupby(). تتلخص هذه المنهجية في ثلاث مراحل متتابعة تُنفذ في الذاكرة دون تدخل يدوي من المستخدم.

في المرحلة الأولى (Split)، تقوم الدالة بفحص العمود الفئوي وتقسيم الإطار الكلي إلى مجموعات افتراضية متباينة بناءً على القيم الفريدة الموجودة فيه، وإنشاء فهرس يربط كل مجموعة بمواقع الصفوف التابعة لها. وفي المرحلة الثانية (Apply)، تُطبق الدالة الإحصائية المستهدفة—وهي mean() في سياقنا—على العمود المحدد داخل كل مجموعة على حدة وبالتوازي. وفي المرحلة الثالثة (Combine)، تُجمع كافة النتائج الفردية المنفصلة وتُدمج في هيكل بياني موحد يعكس المقاييس الإحصائية لجميع الفئات مجتمعة.

يوفر استخدام groupby() تفوقاً هائلاً على التصفية اليدوية المتكررة عبر loc؛ فبدلاً من كتابة حلقات تكرارية تمر على كل فئة منفردة مما يؤدي إلى تعقيد زمني من الدرجة $O(K \times N)$ حيث $K$ هو عدد الفئات و $N$ هو عدد الصفوف، تقوم groupby() بتجزئة البيانات وفهرستها في خطوة واحدة بتعقيد زمني يقارب $O(N)$، مما يحقق وفراً كبيراً في الموارد الحسابية وزمن التنفيذ.

6.2 صياغة واستخدام groupby().mean() للحصول على متوسطات كل الفئات

يتميز استخدام دالة التجميع ببساطته وأناقته البرمجية؛ فبدلاً من كتابة شروط منفصلة لكل فريق، يمكن استخراج جدول متوسط النقاط لجميع الفرق في خطوة واحدة كالتالي: df.groupby('team')['points'].mean(). تعيد هذه الجملة كائن Series مفهرساً بأسماء الفرق، وتوضح القيمة المقابلة لكل فريق متوسطه الحسابي الدقيق.

يدعم التجميع أيضاً التوليفات المتعددة للأعمدة (Multi-level Grouping)؛ مما يتيح حساب المتوسط الشرطي المتقاطع عبر أكثر من بعد تصنيفي، مثل التجميع حسب الفريق وموقع اللعب معاً:

grouped_means = df.groupby(['team', 'position'])['points'].mean()

ينتج عن التجميع متعدد المستويات كائن يحتوي على فهرس هرمي (MultiIndex). لتسهيل التعامل مع المخرجات وإعادتها إلى هيكل جدولي تقليدي ملائم للرسم البياني أو التصدير نحو ملفات خارجية، يُطبق التابع reset_index()، ليتحول الفهرس الهرمي إلى أعمدة عادية وتعود النتيجة بصيغة DataFrame نظيف ومنظم.

6.3 استخدام دالة agg() للتجميع المخصص والمشروط عبر المجموعات

تمنح دالة التجميع المتقدمة agg() (أو aggregate) للمحلل قدرة لا محدودة على تخصيص العمليات الإحصائية وتطبيق مقاييس متباينة عبر مجموعات البيانات في استدعاء برمجي واحد. تتيح هذه الدالة تمرير قائمة من الدوال المدمجة لتُحسب بالتوازي لكل فئة، مثل حساب المتوسط، والوسيط، والانحراف المعياري لعمود النقاط:

df.groupby('team')['points'].agg(['mean', 'median', 'std'])

تتيح دالة agg() أيضاً إمكانية تمرير دوال مخصصة (Custom Functions) أو تعبيرات لامبدا (Lambda Expressions) لتنفيذ شروط خاصة داخل كل مجموعة؛ كأن نحسب متوسط النقاط للاعبين الذين تجاوزوا حداً معيناً داخل كل فريق على حدة:

custom_mean = df.groupby('team')['points'].agg(lambda x: x[x > 15].mean())

لضمان إخراج تقارير إحصائية ذات طابع احترافي، تدعم Pandas ميزة “التجميع المسمى” (Named Aggregation)، والتي تتيح للمستخدم تحديد أسماء مخصصة للأعمدة الناتجة وضبط الدالة المطبقة على كل عمود بصورة دقيقة ومنظمة، مما يمنح الكود وضوحاً كاملاً يسهل تفسيره ومراجعته من قبل فرق العمل المشتركة.

7. استخدام دالة query كبديل مقروء لحساب المتوسطات المشروطة

7.1 بنية دالة df.query() وكيفية تقييم التعبيرات النصية

تمثل دالة df.query() في مكتبة Pandas واجهة برمجية متطورة تتيح تصفية البيانات باستخدام تعبيرات نصية شبيهة بلغة الاستعلامات البنيوية (SQL). تهدف هذه الدالة إلى رفع قابلية قراءة الكود (Readability) والتخلص من التكرار المفرط لكتابة اسم إطار البيانات والأقواس المعقدة المرتبطة بعمليات الفهرسة المنطقية التقليدية.

تعتمد الدالة على تقييم النصوص ديناميكياً باستخدام محرك تقييم متقدم مبني على حزمة NumExpr في الخلفية عند توفرها. يقوم هذا المحرك بتحويل السلسلة النصية إلى شجرة تعبير مجردة (Abstract Syntax Tree) وتجميعها لتعمل مباشرة على مقاطع الذاكرة، متجنباً إنشاء مصفوفات بوليانية مؤقتة في الذاكرة العشوائية لبايثون.

تُصاغ عملية حساب المتوسط الشرطي باستخدام query() بسلاسة فائقة كالتالي:

df.query("team == 'A' and points > 20")['points'].mean()

يلاحظ في هذا السياق إمكانية استخدام الكلمات المفتاحية المنطقية الطبيعية مثل and و or و not بدلاً من العوامل الموضعية، مع استخدام علامات التنصيص المتباينة للفصل بين التعبير النصي الخارجي والقيم النصية الداخلية للفئات، مما يجعل البنية البرمجية مريحة بصرياً وسهلة التتبع والتدقيق.

7.2 تمرير المتغيرات الخارجية والديناميكية إلى query()

تتميز دالة query() بمرونة عالية في التفاعل مع البيئة البرمجية المحيطة بها؛ إذ تتيح للمطورين تضمين المتغيرات المعرفة مسبقاً في نطاق بايثون المحلي أو العام داخل التعبير النصي للاستعلام مباشرة. يُشار إلى المتغير الخارجي داخل النص باستخدام بادئة الرمز الموجه @.

يوضح المثال الآتي كيفية تمرير متغيرات العتبات وفئات التصنيف ديناميكياً إلى الاستعلام الشرطي:

target_team = 'A'
min_assists = 15
result = df.query("team == @target_team and assists >= @min_assists")['points'].mean()

تسهم هذه الميزة في بناء دوال برمجية قابلة لإعادة الاستخدام ووحدات تحليلية تفاعلية؛ حيث يمكن استقبال معايير التصفية كمدخلات من المستخدمين عبر واجهات التطبيقات، ثم تمريرها بأمان إلى الاستعلام لمعالجة البيانات دون الحاجة لإجراء عمليات دمج النصوص اليدوية (String Concatenation) التي قد تعرض النظام لمخاطر حقن الأكواد البرمجية الخبيثة أو الأخطاء التركيبية.

7.3 المفاضلة بين query() و loc من حيث الأداء وقابلية الصيانة

تخضع المفاضلة بين استخدام df.loc[] و df.query() لعدة عوامل تقنية تتعلق بحجم البيانات وسياق المشروع البرمجي. من حيث سرعة التنفيذ، تتفوق طريقة loc في مجموعات البيانات الصغيرة والمتوسطة (أقل من 50,000 صف) نظراً لانعدام التكلفة الإضافية (Overhead) المرتبطة بتحليل النصوص وبناء شجرة التعبير في query().

في المقابل، عند التعامل مع مجموعات البيانات الضخمة التي تحتوي على مئات الآلاف أو الملايين من الصفوف، تستفيد query() من إمكانيات محرك NumExpr الذي يقوم بتجزئة العمليات وتوزيعها على المسارات المتعددة للمعالج (Multithreading)، متفوقاً في كثير من السيناريوهات على الفهرسة التقليدية مع تقليل ملحوظ في استهلاك الذاكرة المؤقتة.

من منظور هندسة البرمجيات، تُفضل query() في الشروط المعقدة والطويلة التي تتضمن مقارنات متعددة لتحسين وضوح الكود وسهولة صيانته من قبل مطورين آخرين، بينما تظل loc الخيار المعياري والأكثر أماناً في الأكواد الداخلية للمكتبات والأنظمة التي تتطلب دعماً مطلقاً لكافة أنواع الكائنات المخصصة والفهارس غير القياسية التي قد لا يدعمها محرك النصوص.

8. تطبيق دالة numpy.where والتضمين الشرطي المباشر (Conditional Masking)

8.1 دمج NumPy مع Pandas لتنفيذ الشروط المتجهية السريعة

تمثل دالة np.where() حلقة الوصل المثالية للجمع بين سرعة مكتبة NumPy الفائقة ومرونة هياكل بيانات Pandas. تعمل هذه الدالة كمعادل متجهي للبنية الشرطية التقليدية (If-Else)، حيث تستقبل ثلاثة معاملات أساسية: المصفوفة الشرطية المنطقية، والقيمة المرجعة عند تحقق الشرط، والقيمة المرجعة عند عدم تحققه.

عند الرغبة في حساب المتوسط الشرطي لعمود مع استبدال القيم غير المطابقة بقيم فارغة لضمان استبعادها من الحساب الإحصائي، تُصاغ المعادلة بالشكل الآتي:

import numpy as np
masked_points = np.where(df['team'] == 'A', df['points'], np.nan)
conditional_mean = np.nanmean(masked_points)

تكمن الميزة الحسابية الكبرى لهذا النهج في التنفيذ المباشر على مستوى لغة C دون إنشاء كائنات وسيطة في بايثون، كما تتيح استخدام الدالة الإحصائية المتخصصة np.nanmean() التي تتجاهل القيم الفارغة بسرعة فائقة، مما يجعل هذا الأسلوب خياراً مفضلاً في الخوارزميات الحسابية كثيفة الاستهلاك للمعالج.

8.2 استخدام دالة mask() و where() المدمجة في Pandas

توفر Pandas نسخاً مدمجة خاصة بها من الدوال الشرطية وهما df.where() و df.mask(). تعمل دالة where() في Pandas بأسلوب عكسي طفيف عن دالة NumPy؛ إذ تحافظ على القيم الأصلية حيثما يكون الشرط صائباً (True)، وتستبدلها بالقيمة المحددة (والتي تكون افتراضياً NaN) عندما يكون الشرط خاطئاً (False)، بينما تعمل mask() كمرآة عاكسة لها تماماً.

لحساب المتوسط الشرطي باستخدام where() المدمجة، نطبق القناع المنطقي مباشرة على عمود النقاط ثم نستدعي دالة المتوسط:

df['points'].where(df['team'] == 'A').mean()

تتميز هذه الطريقة بالحفاظ الكامل على سلامة الفهارس الأصلية للسلسلة (Series Index)، مما يتيح إعادة دمج النتائج أو محاذاتها مع أعمدة أخرى في إطار البيانات دون أي خلل هيكلي، مع توفير واجهة برمجية تتوافق بالكامل مع نمط ربط الدوال المتسلسل (Method Chaining) الشائع في معالجة البيانات الحديثة.

8.3 التعامل مع الشروط المتعددة المتدرجة باستخدام np.select

عندما تتجاوز متطلبات التحليل الشروط الثنائية البسيطة لتشمل تصنيفات متعددة المستويات وقواعد عمل متدرجة، تصبح دالة np.select() الأداة الأكثر قوة وتنظيماً. تقبل الدالة قائمة من الشروط المنطقية المتتابعة وقائمة مقابلة من الخيارات والقيم، مع إمكانية تحديد قيمة افتراضية في حال عدم تحقق أي من الشروط.

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

conditions = [
    df['points'] >= 30,
    (df['points'] >= 15) & (df['points'] < 30),
    df['points'] < 15
]
choices = ['High', 'Medium', 'Low']
df['performance_tier'] = np.select(conditions, choices, default='Unknown')
tier_means = df.groupby('performance_tier')['assists'].mean()

تضمن دالة np.select() تجنب التداخل بين الشروط وتنفذ عمليات الفحص بترتيب أسبقية متسلسل ومنطقي، مما يمنع الأخطاء الشائعة الناتجة عن تكرار الشروط أو تعارضها ويوفر تغطية شاملة لكافة الحالات المتطرفة في البيانات.

9. إدارة القيم المفقودة (NaNs) والبيانات غير المكتملة في الحسابات الشرطية

9.1 سلوك دالة mean() التلقائي مع القيم المفقودة (معامل skipna)

تتميز دالة .mean() في Pandas بوجود سلوك افتراضي صريح للتعامل مع البيانات غير المكتملة، حيث تضبط المعامل الأساسي skipna=True تلقائياً. يعني هذا الإعداد أن المحرك الإحصائي يقوم بإسقاط كافة القيم المفقودة (NaN) من عمود التحليل قبل الشروع في حساب المتوسط، ويُعدل مقام المعادلة الإحصائية ليعكس عدد القيم الصالحة والفعلية فقط وليس إجمالي عدد الصفوف.

ومع ذلك، في البيئات الحسابية العلمية الحساسة التي تتطلب ضمان اكتمال البيانات بالكامل، يمكن ضبط المعامل على skipna=False. في هذه الحالة، إذا احتوت الشريحة المصفاة على قيمة مفقودة واحدة فقط، فإن الدالة سترجع NaN فوراً كإشارة تحذيرية للمحلل بوجود نقص في البيانات يمنع حساب تقدير إحصائي دقيق.

يجب التمييز بوضوح بين وجود القيم المفقودة في العمود المستهدف بالتحليل (عمود القيم) ووجودها في العمود المستخدم لفرض الشرط؛ إذ إن وجود NaN في عمود الشرط ينتج قيماً غير محددة تؤدي تلقائياً إلى استبعاد تلك الصفوف من القناع البولياني، مما قد يخفض حجم العينة الإحصائية دون تنبيه صريح للمحلل.

9.2 تصفية القيم المفقودة صراحة قبل تطبيق الشروط الإحصائية

تقتضي أفضل الممارسات في هندسة البيانات فحص وتنظيف النطاقات الشرطية صراحة قبل الشروع في الحسابات الإحصائية، وذلك بالاعتماد على الدوال المخصصة مثل notna() أو isna(). يضمن هذا النهج السيطرة الكاملة على تدفق البيانات وتجنب المقارنات المنطقية الخاطئة؛ حيث تفشل المقارنة التقليدية NaN == NaN دائماً في معايير IEEE 754 وتنتج False دائماً.

لحساب متوسط نقاط اللاعبين مع ضمان وجود قيم غير فارغة في كل من عمود الفريق وعمود النقاط، يُصاغ الكود الوقائي كالتالي:

valid_mask = df['team'].notna() & df['points'].notna() & (df['team'] == 'A')
clean_mean = df.loc[valid_mask, 'points'].mean()

يسهم هذا الأسلوب في الحفاظ على استقرار البرمجيات التحليلية في بيئات الإنتاج الفعلية، حيث تتدفق البيانات الحية محملة في كثير من الأحيان بفجوات ونواقص قد تعطل النظم الإحصائية الهشة أو تؤدي إلى نتائج غير موثوقة تؤثر سلباً على اتخاذ القرارات.

9.3 طرق معالجة وتعويض البيانات المفقودة (Imputation) وتأثيرها على المتوسط الشرطي

يعد تعويض البيانات المفقودة (Imputation) مرحلة متقدمة تتجاوز مجرد الحذف البسيط للقيم الناقصة. يُعد التعويض باستخدام المتوسط الشرطي للفئة (Group Mean Imputation) تقنية إحصائية متفوقة بمراحل على التعويض بالمتوسط العام للبيانات ككل، حيث يحافظ على الخصائص التوزيعية والتباينات البينية لكل مجموعة دون تشويه.

توفر دالة transform() المدمجة مع groupby() وسيلة أنيقة لتنفيذ هذا التعويض الموجه بأسلوب متجهي كامل:

df['imputed_points'] = df['points'].fillna(df.groupby('team')['points'].transform('mean'))

تقوم هذه العملية بحساب متوسط النقاط الخاص بكل فريق على حدة، ثم استخدامه حصرياً لملء الفراغات الموجودة لدى لاعبي ذلك الفريق نفسه. على الرغم من فاعلية هذه التقنية في الحفاظ على النزعة المركزية، يجب الانتباه إلى أنها تؤدي بطبيعتها إلى تقليص التباين (Variance) الداخلي للمجموعة بصورة مصطنعة، مما يتطلب تقييماً دقيقاً للأثر الإحصائي قبل استخدام البيانات المعوضة في اختبارات الفرضيات أو النمذجة المتقدمة.

10. تحليل الأداء والكفاءة الحسابية عند معالجة البيانات الضخمة (Big Data Optimization)

10.1 قياس واختبار سرعة التنفيذ (Benchmarking) للطرق المختلفة

تتباين الطرق البرمجية لحساب المتوسط الشرطي تفاوتاً كبيراً في استهلاك الموارد وسرعة التنفيذ، ويتجلى هذا التباين بوضوح عند التعامل مع مجموعات البيانات الكبيرة التي تتجاوز ملايين السجلات. توفر بيئات بايثون التحليلية مثل Jupyter الأدوات السحرية لقياس الأداء الزمني مثل %timeit لإجراء مقارنات دقيقة ومكررة إحصائياً بين الاستراتيجيات المختلفة.

توضح التجارب المعيارية على مصفوفة بيانات تحتوي على 10 ملايين صف أن استخدام العمليات المتجهية عبر loc أو NumPy يحقق سرعة تنفيذ تتراوح بين 10 إلى 50 جزءاً من الألف من الثانية، بينما يؤدي استخدام query() إلى أداء مقارب مع تحسن ملحوظ في إدارة الذاكرة عند تفعيل NumExpr. في المقابل، تظهر عمليات groupby() تفوقاً استثنائياً عندما يكون الهدف استخراج المتوسطات لكافة الفئات دفعة واحدة بدلاً من استدعاء التصفية المنفصلة لكل فئة.

يرافق قياس الأداء الزمني تحليل استهلاك الذاكرة (Memory Profiling)؛ حيث تتطلب بعض الطرق إنشاء نسخ وسيطة للبيانات أثناء التصفية مما يرفع الضغط على الذاكرة العشوائية (RAM Spike)، في حين تحافظ الطرق الموجهة المحسنة على بقاء المؤشرات في حيز الذاكرة الأصلي قدر الإمكان.

10.2 تجنب الحلقات التكرارية والحلول غير الفعالة (Iterrows & Loops Anti-patterns)

يعد استخدام الحلقات التكرارية الصريحة مثل for loop أو التوابع التكرارية المدمجة مثل iterrows() و itertuples() لحساب المتوسطات الشرطية من أسوأ الأنماط البرمجية (Anti-patterns) في مجتمع بايثون، لما تسببه من انهيار دراماتيكي في الأداء الحسابي والزمني للبرمجيات.

تكمن علة البطء الشديد في أن df.iterrows() تقوم في كل خطوة تكرارية بتحويل صف البيانات من مصفوفة C المحسنة إلى كائن Series مستقل في بايثون، مما يضيف تكلفة تشغيلية باهظة ناجمة عن إدارة كائنات بايثون (Object Overhead) والتحقق المستمر من الأنواع والفهارس. يؤدي هذا إلى استغراق دقائق طويلة لحساب متوسط شريحة بسيطة يمكن للعمليات المتجهية معالجتها في بضعة أجزاء من الثانية.

تضمن المعالجة المتجهية تشغيل خوارزميات الجمع والتصفية داخل شفرات C المجمعة مسبقاً، مع استغلال ممرات النقل العريضة في المعالجات الحديثة وخاصية التنبؤ بالتفرع (Branch Prediction)، مما يجعل التحول من الحلقات التكرارية إلى المتجهات ضرورة تقنية حتمية عند بناء مسارات معالجة البيانات الضخمة.

10.3 تحسين أنواع البيانات (Data Types Optimization) لتسريع العمليات الشرطية

يرتبط الأداء الحسابي للعمليات الشرطية ارتباطاً وثيقاً بالهندسة الدقيقة للأنواع البيانية (Data Types) المخزنة في الذاكرة. تقوم Pandas افتراضياً بتعيين نوع البيانات object للأعمدة النصية ونوع int64 أو float64 للأعمدة العددية، وهي إعدادات عامة تستهلك مساحات ذاكرة تفوق الحاجة الفعلية في معظم السيناريوهات.

يؤدي تحويل الأعمدة الفئوية ذات التكرارات المحدودة من نوع object إلى category إلى خفض استهلاك الذاكرة بنسبة قد تتجاوز 80%، كما يسرع من عمليات مقارنة الشروط بمقدار الضعف أو أكثر. كما يسهم تقليص حجم المتغيرات العددية غير الحرجة (Downcasting) من float64 إلى float32 أو استخدام الأنواع الصحيحة المناسبة مثل int32 في مضاعفة عدد العناصر التي يمكن تضمينها في ذاكرة التخزين المؤقت للمعالج (CPU Cache L1/L2)، مما يرفع كفاءة وسرعة المعالجة الشرطية بشكل ملحوظ.

يوضح الجدول الآتي مقارنة شاملة بين الطرق المختلفة لحساب المتوسط الشرطي من حيث التعقيد، والسرعة، والاستخدام الموصى به:

الأسلوب البرمجي السرعة النسبية استهلاك الذاكرة أبرز الاستخدامات ومواطن القوة
df.loc[condition, col].mean() سريع جداً منخفض (إنشاء أقنعة فقط) حساب المتوسط لشرط محدد ومباشر؛ المعيار البرمجي الأساسي.
df.query().mean() سريع إلى ممتاز ممتاز مع مجموعات البيانات الضخمة الشروط المعقدة والمتعددة التي تتطلب كوداً مقروءاً ومحرك NumExpr.
np.where() / np.select() فائق السرعة منخفض للغاية الخوارزميات منخفضة المستوى والعمليات المشروطة متدرجة الحالات.
df.groupby().mean() فائق السرعة متوسط إلى ممتاز استخراج متوسطات كافة الفئات دفعة واحدة بآلية Split-Apply-Combine.
الحلقات التكرارية (iterrows) بطيء للغاية (غير مقبول) مرتفع بسبب كائنات بايثون يجب تجنبه تماماً في بيئات التحليل والإنتاج.

11. تطبيقات ودراسات حالة عملية من واقع الأعمال وتحليل البيانات

11.1 دراسة حالة رياضية: تحليل إحصائيات الفرق واللاعبين

في التحليلات الرياضية الحديثة، لم تعد المؤشرات الإجمالية كافية لتقييم كفاءة الفرق؛ بل أصبحت القرارات التكتيكية تُبنى على مقاييس مشروطة بالسياق التنافسي. يمكن للمحلل تقييم كفاءة الفريق ‘A’ عبر مقارنة متوسط نقاطه المسجلة في المباريات المقامة داخل ملعبه مقارنة بالمباريات الخارجية عبر التعبير:

home_mean = df.loc[(df['team'] == 'A') & (df['venue'] == 'Home'), 'points'].mean()
away_mean = df.loc[(df['team'] == 'A') & (df['venue'] == 'Away'), 'points'].mean()

يمتد التحليل ليشمل تقييم كفاءة اللاعبين تحت ضغط دفاعي معين؛ كأن يُحسب متوسط فاعلية التسديد للاعبي الخط الخلفي عندما تتجاوز دقائق اللعب 30 دقيقة ويكون الفارق النقطي أقل من 5 نقاط. تكشف هذه المتوسطات المشروطة المستويات الحقيقية لثبات الأداء وصمود الاستراتيجيات التكتيكية في اللحظات الحاسمة من المنافسات الرياضية.

11.2 دراسة حالة تجارية: تحليل سلوك العملاء والمبيعات (E-commerce)

يمثل حساب “متوسط قيمة الطلب” (Average Order Value – AOV) ركيزة أساسية في قطاع التجارة الإلكترونية، إلا أن قيمته الاستراتيجية تتضاعف عند تقييده بالشرائح السلوكية والزمنية المختلفة للمستهلكين. يتيح حساب هذا المؤشر للعملاء الجدد مقارنة بالعملاء العائدين تحديد كفاءة استراتيجيات الاحتفاظ بالعملاء وتأثيرها على الإيرادات.

يوضح الكود الآتي كيفية حساب متوسط إنفاق العملاء المشروط باستخدام القسائم الترويجية خلال فترات التخفيضات الكبرى:

promo_aov = df.loc[(df['used_coupon'] == True) & (df['season'] == 'BlackFriday'), 'order_total'].mean()

يساعد هذا التحليل الشرطي متخذي القرار في قطاع التسويق على قياس “عائد الاستثمار التسويقي” بدقة، ومعرفة ما إذا كانت الخصومات ترفع سلة المشتريات الفعلية للمستهلك أم أنها تقتطع من هوامش الربح دون زيادة ملموسة في متوسط قيمة الطلب الإجمالي للشركة.

11.3 دراسة حالة علمية / استبيانية: تحليل درجات المقاييس النفسية والتقييمية

في الأبحاث النفسية والاجتماعية التي تعتمد على مقاييس ليكرت (Likert Scales) والاستبيانات المعيارية، تُستخدم المتوسطات المشروطة لفحص الفروق الدقيقة بين المجموعات السكانية والديموغرافية المختلفة. على سبيل المثال، قد يهتم الباحث بحساب متوسط درجات مقياس القلق الوظيفي مقيداً بساعات العمل الأسبوعية وفئة العمر المهني.

تُطبق الشروط لاستخلاص متوسط درجات الرضا لدى الموظفين الذين يعملون بنظام العمل عن بُعد وتتجاوز سنوات خبرتهم 5 سنوات:

remote_satisfaction = df.loc[(df['work_model'] == 'Remote') & (df['experience_years'] > 5), 'satisfaction_score'].mean()

تُشكل هذه المتوسطات المشروطة المدخلات الأساسية للاختبارات الإحصائية الاستدلالية اللاحقة، مثل اختبارات T-Test وتحليل التباين (ANOVA)، للتحقق من الدلالة الإحصائية للفروق الظاهرة وتفسير المتغيرات التفاعلية الكامنة في بنية المجتمع البحثي.

12. الأخطاء الشائعة، استكشاف المشكلات، وأفضل الممارسات البرمجية

12.1 تحذير النسخ مع التعيين (SettingWithCopyWarning) وأسبابه

يعد تحذير SettingWithCopyWarning أحد أكثر الرسائل إثارة للحيرة لدى المطورين في مكتبة Pandas. ينشأ هذا التحذير عندما يحاول المبرمج تعديل قيم مصفوفة جزئية جرى تصفيتها عبر الفهرسة المتسلسلة (Chained Indexing) مثل df[df['team'] == 'A']['points'] = ...؛ حيث يعجز المحرك الداخلي عن تحديد ما إذا كان التعديل سيؤثر على الإطار الأصلي أم على نسخة مؤقتة في الذاكرة.

لتجنب هذا التحذير وضمان سلامة البيانات عند حساب المتوسطات وتعيين نتائجها، يجب استخدام الفهرسة المباشرة عبر .loc حصراً. وفي الحالات التي تتطلب عزل شريحة البيانات المشروطة في كائن مستقل لإجراء معالجات إضافية، يجب استخدام التابع الصريح .copy() لفك الارتباط بالذاكرة الأصلية تماماً:

team_a_df = df.loc[df['team'] == 'A'].copy()
team_a_mean = team_a_df['points'].mean()

يحمي هذا الإجراء مسار المعالجة من التأثيرات الجانبية غير المقصودة (Side Effects)، ويضمن استقلالية الكائنات الفرعية واستقرار العمليات الحسابية داخل البيئات الإنتاجية الحساسة.

12.2 أخطاء أولوية المعاملات المنطقية ومشكلات الأنواع البيانية

يقع كثير من المحللين في خطأ إهمال الأقواس الدائرية عند دمج الشروط المنطقية باستخدام & أو |، مما يؤدي إلى ظهور أخطاء تركيبية مثل TypeError: cannot compare a dtyped [int64] array with a scalar of type [bool]. ينجم هذا الخطأ عن محاولة بايثون تطبيق العامل الموضعي على قيمتين وسيطتين قبل اكتمال مقارنة الأطراف.

تتمثل مشكلة شائعة أخرى في مقارنة الأعمدة العددية المخزنة بنوع نصوص (String-encoded numbers)؛ حيث تفشل المقارنة df['points'] > 20 صامتاً أو تعطي نتائج مغلوطة مبنية على الترتيب الأبجدي للنصوص بدلاً من الترتيب الرياضي للأرقام. يجب دائماً التحقق من أنواع البيانات باستخدام df.dtypes والتحويل الصريح عبر pd.to_numeric() قبل بناء الشروط الإحصائية.

علاوة على ذلك، يجب الانتباه إلى معالجة الشروط التي تُرجع سلاسل فارغة (Empty Slices)؛ حيث يرجع استدعاء .mean() عليها القيمة NaN. يجب بناء منطق برمجي وقائي للتحقق من حجم المصفوفة أو استخدام دالة np.nan_to_num() لاستبدال النتائج غير المعرفة بقيم افتراضية مناسبة تضمن استمرار تنفيذ الأنظمة دون توقف مفاجئ.

12.3 قائمة التحقق المرجعية (Checklist) لكتابة كود إحصائي متين وقابل للتوسع

لضمان كتابة كود إحصائي متين، عالي الأداء، وخالٍ من العيوب البرمجية في المشاريع الواقعية، يُنصح بالالتزام بقائمة التحقق المنهجية الآتية قبل اعتماد أي مسار لمعالجة المتوسطات المشروطة:

  • التحقق من أنواع البيانات (Data Types): التأكد من تحويل الأعمدة الفئوية إلى category والأعمدة العددية إلى الأنواع الرقمية الصريحة وتفادي تخزين الأرقام كسلاسل نصية.
  • تنظيف القيم المفقودة (Handling NaNs): فحص وجود القيم الفارغة في أعمدة الشروط وأعمدة القيم وضبط المعامل skipna وتحديد سلوك المعالجة صراحة باستخدام notna().
  • استخدام الأقواس المنطقية الإلزامية: إحاطة كل تعبير شرطي منفصل بالأقواس () عند استخدام العوامل الموضعية (&, |, ~).
  • تفضيل الفهرسة المباشرة عبر .loc: تجنب الفهرسة المتسلسلة واستخدام .loc[rows, cols] دائماً لمنع تحذيرات النسخ وضمان استقرار الذاكرة.
  • اختيار الأداة المناسبة لحجم البيانات: استخدام loc للشروط البسيطة، و groupby() للتجميع الشامل، و query() للبيانات الضخمة والشروط المعقدة، و np.select() للحالات المتدرجة.
  • كتابة اختبارات الوحدة (Unit Testing): صياغة اختبارات آلية باستخدام مكتبات مثل pytest للتحقق من صحة مخرجات المتوسطات المشروطة على عينات بيانات مصغرة ومعلومة النتائج مسبقاً.
  • توثيق الشروط البرمجية: إضافة تعليقات شارحة وتسمية المتغيرات بأسماء واضحة تعبر بدقة عن المفهوم الإحصائي والشرط المطبق لتسهيل قراءة الكود وصيانته مستقبلاً.

خاتمة

يعد حساب المتوسط الحسابي الشرطي في بيئة مكتبة Pandas أداة تحليلية محورية تجمع بين عمق النظرية الإحصائية وكفاءة الهندسة البرمجية. من خلال استيعاب الآليات الداخلية للفهرسة المنطقية عبر .loc، وقوة التجميع الشامل باستخدام groupby()، ومرونة التعبيرات النصية في query()، والتسريع الحسابي الموجه بواسطة دمج دوال NumPy، يكتسب المحلل القدرة على تحويل البيانات الخام المعقدة إلى رؤى إحصائية واضحة المعالم وذات قيمة عملية عالية.

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

References

اقتباس هذا المقال

looti, M. (2026, سبتمبر 1). كيفية حساب المتوسط الشرطي في بانداز (مع أمثلة). عرب سايكلوجي. https://arabpsychology.com/statistics/how-to-calculate-conditional-mean-in-pandas-with-examples/
looti, Mohammed. “كيفية حساب المتوسط الشرطي في بانداز (مع أمثلة).” عرب سايكلوجي, 1 سبتمبر 2026, https://arabpsychology.com/statistics/how-to-calculate-conditional-mean-in-pandas-with-examples/.
looti, Mohammed. “كيفية حساب المتوسط الشرطي في بانداز (مع أمثلة).” عرب سايكلوجي. سبتمبر 1, 2026. https://arabpsychology.com/statistics/how-to-calculate-conditional-mean-in-pandas-with-examples/.