بايثون وبانداز, علم البيانات

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


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

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

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

1. مقدمة شاملة لمفهوم الرتبة المئوية (Percentile Rank) وأهميتها الإحصائية

1.1 التعريف النظري للرتبة المئوية

تُعرّف الرتبة المئوية (Percentile Rank) في علم الإحصاء بأنها مقياس موضعي نسبي يُحدد النسبة المئوية للدرجات أو القيم في توزيع تكراري معين والتي تقع تحت درجة معينة أو تساويها. على عكس المقاييس الإحصائية المطلقة كالمتوسط الحسابي أو الانحراف المعياري، تقدم الرتبة المئوية فهماً فورياً لموقع المشاهدة دون التأثر بشكل التوزيع الإحصائي سواء كان توزيعاً طبيعياً متماثلاً (Normal Distribution) أو توزيعاً ملتوياً (Skewed Distribution). يُعبر هذا المفهوم عن المكانة التنافسية أو النسبية للبيانات الفردية داخل المجتمع الإحصائي بأكمله، مما يجعله أداة محورية في تقييم الأداء والمقارنات المعيارية.

من الضروري جداً التمييز الدقيق بين مفهوم الرتبة المئوية (Percentile Rank) والمئين (Percentile)؛ حيث يقع الكثير من المبتدئين في خلط منهجي بين المصطلحين. المئين هو قيمة المتغير المقابلة لنقطة مئوية محددة (أي القيمة الفعلية على مقياس القياس)، مثل قولنا: “المئين التسعون لاختبار الذكاء هو 130 درجة”. أما الرتبة المئوية فهي النسبة المئوية للأفراد أو المشاهدات الذين حققوا درجة أقل من تلك القيمة أو مساوية لها، كأن نقول: “الطالب الذي حصل على 130 درجة يقع في الرتبة المئوية 90%”. وبالتالي، فإن المئين هو درجة قياسية، بينما الرتبة المئوية هي نسبة تراكمية تصف موضع تلك الدرجة.

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

1.2 دور مكتبة بانداز في الحوسبة الإحصائية

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

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

2. الأسس الرياضية لحساب الرتبة المئوية في علم البيانات

2.1 المعادلات الحسابية الأساسية للرتبة المئوية

تستند الرتبة المئوية من الناحية الرياضية إلى حساب دالة التوزيع التراكمي التجريبية (Empirical Cumulative Distribution Function). في صورتها التقليدية المبسطة لمجموعة بيانات تتكون من عينة حجمها الإجمالي $N$، يتم ترتيب القيم تصاعدياً من الأصغر إلى الأكبر، وتُحسب الرتبة المئوية للدرجة $X$ وفق الصيغة التالية:

$$\text{Percentile Rank} = \left( \frac{\text{Count}(y < X) + 0.5 \times \text{Count}(y = X)}{N} \right) \times 100$$

حيث يمثل $\text{Count}(y < X)$ عدد القيم التي تقل تماماً عن القيمة المستهدفة $X$، ويمثل $\text{Count}(y = X)$ عدد القيم المكررة المتطابقة مع القيمة $X$. تعكس إضافة نصف وزن القيم المتطابقة تصحيحاً رياضياً لتجنب الانحياز وضمان توزيع الرتب بشكل متوازن حول المركز الإحصائي.

يلعب حجم العينة الإجمالي $N$ دوراً حاسماً في الدقة التفسيرية للرتبة المئوية المحسوبة. في العينات الصغيرة جداً (على سبيل المثال، $N = 10$)، تؤدي قفزة رتبة واحدة إلى تغيير في الرتبة المئوية بمقدار 10% كاملة، مما يجعل التقديرات عرضة لتقلبات خطأ المعاينة (Sampling Error). في المقابل، عندما يكبر حجم العينة في مجموعات البيانات الضخمة، تصبح التغيرات بين الرتب المئوية المتتالية متناهية في الصغر ومستمرة، مما يوفر تمثيلاً دقيقاً وموثوقاً لموقع الفرد أو المشاهدة داخل التوزيع الإحصائي الأصلي.

2.2 الرتبة المئوية في التحليل السيكومتري والقياس النفسي

في مجالات القياس النفسي والتربوي (Psychometrics)، تُعد الرتب المئوية المعيار الذهبي لتفسير درجات الاختبارات المعيارية مثل اختبارات الذكاء (IQ)، واختبارات القدرات العامة، والمقاييس السلوكية. الدرجة الخام (Raw Score) التي يحصل عليها المفحوص لا تحمل بمفردها أي معنى سريري أو تقييمي محدد؛ إذ إن الحصول على 80 درجة من أصل 100 قد يعني أداءً متميزاً إذا كان الاختبار بالغ الصعوبة، أو أداءً متواضعاً إذا كان الاختبار سهلاً جداً وحقق معظم المتقدمين درجات تتجاوز 90.

من خلال تحويل الدرجات الخام إلى رتب مئوية بالرجوع إلى عينة معيارية ممثلة للمجتمع (Normative Sample)، يستطيع الأخصائي النفسي أو مسؤول التقييم تحديد الموقع الدقيق للفرد. فإذا كانت الرتبة المئوية للمفحوص هي 85%، فإن التفسير المباشر والموضوعي هو أن أداء هذا الفرد يعادل أو يتفوق على 85% من أفراد العينة المعيارية المقارنة، بينما يتفوق عليه 15% فقط. يضمن هذا التحويل العدالة والموضوعية في التقييم ويجعل النتائج قابلة للفهم التام من قِبل غير المتخصصين كالمدراء وأولياء الأمور وصناع القرار.

3. إعداد بيئة العمل وإنشاء إطار البيانات (DataFrame)

3.1 استيراد الحزم الضرورية وتهيئة البيئة

لبدء العمل التحليلي والحسابي في بايثون، يتعين استدعاء المكتبات البرمجية الأساسية لإدارة البيانات والحسابات الإحصائية. المكتبة الأساسية المعتمدة هي مكتبة بانداز، ويتم استيرادها تحت الاسم المختصر الشائع pd. كما يُفضل استيراد مكتبة نمباي تحت الاسم المختصر np لتسهيل التعامل مع القيم الرياضية المفقودة والمصفوفات المتقدمة. علاوة على ذلك، يُنصح بضبط خيارات عرض البيانات في بانداز لتحسين تنسيق الأرقام ودقة المنازل العشرية في بيئات التطوير مثل Jupyter Notebook أو Google Colab.

تتم تهيئة البيئة البرمجية من خلال تنفيذ الأوامر التالية:

import pandas as pd
import numpy as np

# ضبط خيارات العرض للأرقام العشرية
pd.set_option('display.float_format', lambda x: '%.4f' % x)

يضمن ضبط خيار display.float_format أن تظهر النتائج الإحصائية بدقة محددة تتضمن أربع منازل عشرية، وهو أمر بالغ الأهمية عند معاينة الرتب المئوية بدقة وتجنب التشتت البصري الناتج عن الأرقام العشرية الطويلة غير المنتهية.

3.2 بناء مجموعة بيانات تجريبية (Sample Dataset)

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

يمكن بناء إطار البيانات باستخدام القاموس البرمجي التالي في بايثون:

data = {
    'Employee_ID': [101, 102, 103, 104, 105, 106, 107, 108, 109, 110],
    'Department': ['Sales', 'Sales', 'Sales', 'Sales', 'Sales', 'IT', 'IT', 'IT', 'IT', 'IT'],
    'Performance_Score': [45, 67, 89, 67, 92, 55, 78, 88, 78, 95],
    'Experience_Years': [2, 4, 7, 3, 10, 1, 5, 6, 5, 12]
}

df = pd.DataFrame(data)
print(df.info())
print(df.head())

تسمح دالة df.info() بالتحقق من أنواع البيانات (Data Types) والتأكد من أن المتغيرات الكمية محددة كأعداد صحيحة (int64) أو أعداد عشرية (float64)، وعدم وجود قيم نصية غير مقصودة قد تعيق العمليات الإحصائية الرياضية اللاحقة.

4. الطريقة الأولى: حساب الرتبة المئوية لعمود كامل باستخدام الدالة rank(pct=True)

4.1 بنية واستخدام المعامل pct=True

توفر مكتبة بانداز الدالة المدمجة rank() كأداة رئيسية وشاملة لحساب الرتب الإحصائية للبيانات في الأعمدة (Series) أو مصفوفات البيانات الكاملة. افتراضياً، تقوم الدالة rank() بحساب الرتب المطلقة (أي الأعداد الصحيحة 1، 2، 3، … $N$). غير أن القوة الحقيقية للدالة تكمن في تضمين المعامل المنطقي pct=True، والذي يوجه المحرك الحسابي لتحويل الرتب المطلقة مباشرة إلى نسب مئوية تتراوح قيمتها الرياضية بدقة بين 0 و 1 (أو كسر عشري يعبر عن الرتبة التراكمية النسبية).

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

df['Overall_Percentile_Rank'] = df['Performance_Score'].rank(pct=True)

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

4.2 تحويل النسب العشرية إلى قيم مئوية قابلة للقراءة

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

لتحقيق ذلك، نقوم بضرب العمود المحسوب في الرقم 100 واستخدام دالة التقريب round()، أو تطبيق تنسيق نصي (String Formatting) لإلحاق علامة النسبة المئوية:

# حساب الرتبة كنسبة مئوية صريحة مع التقريب لرقمين عشريين
df['Percentile_Rank_Pct'] = (df['Performance_Score'].rank(pct=True) * 100).round(2)

# إضافة الرمز المئوي للتقارير النهائية
df['Formatted_Rank'] = df['Percentile_Rank_Pct'].astype(str) + '%'

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

5. استراتيجيات معالجة القيم المكررة (Ties) في حساب الرتب

5.1 طرق معالجة التكرار الافتراضية والبديلة في بانداز

تُمثل القيم المتساوية أو المكررة (Ties) أحد التحديات الإحصائية المركزية في حساب الرتب. عندما تتطابق قيمتان أو أكثر في عمود البيانات، يجب أن يتبع النظام الرياضي قاعدة منهجية محددة لتوزيع الرتب بين هذه القيم. توفر دالة rank() في بانداز المعامل method الذي يدعم خمس استراتيجيات متمايزة لمعالجة التكرارات بما يخدم الأهداف الإحصائية المختلفة للمحلل.

الطريقة الافتراضية هي طريقة المتوسط (method='average'). في هذه الطريقة، إذا تساوت قيمتان في المركزين 3 و 4، يقوم البرنامج بجمع الرتبتين وقسمتهما على 2، لتحصل كلتا القيمتين على الرتبة 3.5. هذه الطريقة هي الأكثر قبولاً في الإحصاء البارامتري واللامعلمي لأنها تحافظ على مجموع الرتب ثابتاً وتمنع التحيز الرياضي للتوزيع.

تتمثل البدائل الشائعة في طريقة الحد الأدنى (method='min') وطريقة الحد الأقصى (method='max'). في طريقة min، تُمنح القيم المتطابقة أدنى رتبة متاحة لها في المجموعة المتساوية (كأن تأخذ القيمتان المتساويتان الرتبة 3)، وهو النمط المتبع في لوائح المتصدرين الرياضية. أما في طريقة max، فتُمنح جميع القيم المتطابقة الرتبة الأعلى المتاحة (كأن تأخذ القيمتان الرتبة 4)، وهو ما يؤثر مباشرة على حساب الرتبة المئوية الناتجة برفعها أو خفضها نسبياً.

5.2 الطرائق المتقدمة: First و Dense

توفر بانداز خيارين إضافيين بالغي الأهمية للتحليلات المتقدمة: طريقة الترتيب الأسبق (method='first') وطريقة الترتيب المكثف (method='dense').

تعتمد طريقة method='first' على ترتيب المشاهدات المتطابقة بناءً على موضع ظهورها الزمني أو المكاني في إطار البيانات الأصلي (موقع الفهرس Index). تحصل المشاهدة الأولى على الرتبة الأدنى والمشاهدة التي تليها على الرتبة الأعلى، مما يلغي وجود أي تكرار عددي في عمود الرتب المئوية ويجعل كل رتبة فريدة بشكل قاطع.

أما طريقة method='dense'، فتشبه طريقة min من حيث منح القيم المتطابقة نفس الرتبة، ولكنها تختلف جذرياً في كيفية التعامل مع القيمة التالية. في طريقة الترتيب المكثف، لا يتم تخطي أي رقم في تسلسل الرتب؛ فالرتبة التي تلي مجموعة حاصلة على الرتبة 3 ستكون الرتبة 4 مباشرة، حتى وإن ضمت المجموعة السابقة ثلاث مشاهدات متكررة. يوضح الجدول البرمجي التالي كيفية استدعاء هذه الطرق في بايثون:

df['Rank_Avg'] = df['Performance_Score'].rank(method='average', pct=True)
df['Rank_Min'] = df['Performance_Score'].rank(method='min', pct=True)
df['Rank_Max'] = df['Performance_Score'].rank(method='max', pct=True)
df['Rank_First'] = df['Performance_Score'].rank(method='first', pct=True)
df['Rank_Dense'] = df['Performance_Score'].rank(method='dense', pct=True)

يجب على المحلل اختيار الطريقة التي تتوافق بدقة مع الفلسفة النظرية للبحث؛ فطريقة dense مفيدة جداً عند تقسيم البيانات إلى شرائح مئوية متساوية العرض الترتيبي، بينما تعتبر average الخيار الأكاديمي القياسي لمعظم التحليلات الإحصائية الوصفية والاستدلالية.

6. الطريقة الثانية: حساب الرتبة المئوية حسب المجموعات (GroupBy & Transform)

6.1 آلية تقسيم وتطبيق وتجميع البيانات (Split-Apply-Combine)

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

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

تتم صياغة الكود البرمجي المتقدم لهذا التحليل على النحو التالي:

df['Dept_Percentile_Rank'] = (
    df.groupby('Department')['Performance_Score']
    .transform(lambda x: x.rank(pct=True))
)

أو باستخدام الصيغة المبسطة الأكثر كفاءة وسرعة في التنفيذ الحوسبي:

df['Dept_Percentile_Rank'] = (
    df.groupby('Department')['Performance_Score']
    .transform('rank', pct=True)
)

6.2 مقارنة الرتب بين المجموعات المختلفة

يوفر التحليل الفئوي عبر transform رؤى معمقة قد تغفلها التحليلات الإجمالية. قد يحصل موظف على درجة تقييم مطلقة قدرها 78، وتكون رتبته المئوية الإجمالية في الشركة هي 50% (أي متوسط الأداء العام). ولكن عند حساب رتبته المئوية داخل قسم تقنية المعلومات (IT) الذي يتسم بمتوسط درجات منخفض، قد تقفز رتبته المئوية إلى 75%، مما يشير إلى تميزه النسبي بين أقرانه المباشرين.

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

7. تطبيق عملي: تحليل شامل لمجموعة بيانات معقدة

7.1 تنفيذ الكود خطوة بخطوة على بيانات النقاط والفرق

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

يوضح الكود التالي الخطوات البرمجية المتكاملة:

import pandas as pd
import numpy as np

# 1. إنشاء مجموعة بيانات متقدمة
raw_data = {
    'Employee': ['Ahmed', 'Sara', 'Khaled', 'Mona', 'Omar', 'Zaid', 'Fatima', 'Youssef', 'Huda', 'Ali'],
    'Team': ['Alpha', 'Alpha', 'Alpha', 'Alpha', 'Alpha', 'Beta', 'Beta', 'Beta', 'Beta', 'Beta'],
    'Projects_Completed': [12, 18, 25, 18, 30, 10, 15, 22, 15, 28]
}

df_projects = pd.DataFrame(raw_data)

# 2. حساب الرتبة المئوية الإجمالية لجميع الموظفين (Overall)
df_projects['Overall_PR'] = (
    df_projects['Projects_Completed']
    .rank(method='average', pct=True) * 100
).round(1)

# 3. حساب الرتبة المئوية ضمن كل فريق على حدة (Within Team)
df_projects['Team_PR'] = (
    df_projects.groupby('Team')['Projects_Completed']
    .transform('rank', method='average', pct=True) * 100
).round(1)

# 4. حساب فرق الترتيب بين القياسين
df_projects['PR_Difference'] = (df_projects['Team_PR'] - df_projects['Overall_PR']).round(1)

print(df_projects)

7.2 قراءة المخرجات وتفسيرها تحليلياً

عند فحص المخرجات الناتجة من الكود السابق، نلاحظ تجليات إحصائية بارزة تبرهن على أهمية الجمع بين التحليل الكلي والفئوي. الموظف الذي يحمل الاسم ‘Omar’ حقق 30 مشروعاً مكتملة، وهي أعلى قيمة في البيانات، وحصل بالتالي على رتبة مئوية إجمالية 100% ورتبة مئوية داخل فريقه (Alpha) بلغت 100% أيضاً، مع فارق صفري بين الرتبتين.

في المقابل، لنفحص حالة الموظفة ‘Fatima’ في الفريق (Beta) التي أنجزت 15 مشروعاً بالتساوي مع زميلها ‘Huda’. رتبتها المئوية الإجمالية بلغت 35% فقط؛ نظراً لأن الفريق (Alpha) يضم أعضاء حققوا أرقاماً أعلى. ولكن عند تقييمها حصرياً داخل الفريق (Beta)، ارتفعت رتبتها المئوية إلى 50%، نظراً لأن الفريق يضم عضواً أقل أداءً (Zaid بـ 10 مشاريع).

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

8. التعامل مع القيم المفقودة (NaNs) في حسابات الرتبة المئوية

8.1 خيارات المعامل na_option في دالة rank

تُعد مشكلة القيم المفقودة (Missing Values أو NaN) من الظواهر الحتمية والشائعة في قواعد البيانات الواقعية. توفر دالة rank() في بانداز مرونة استثنائية لإدارة هذه المشاهدات من خلال المعامل na_option، والذي يقبل ثلاثة خيارات رئيسية تؤثر بشكل جذري على النتائج الحسابية:

  • na_option='keep': وهو الخيار الافتراضي، وفيه تُترك القيم المفقودة كما هي كقيم NaN في عمود الرتب الناتج، مع استبعادها التام من حساب الرتب للقيم الصالحة الأخرى (أي تصبح $N$ مساوية لعدد القيم غير المفقودة فقط).
  • na_option='bottom': يتم إسناد أدنى رتبة ممكنة للقيم المفقودة وتوضع في نهاية التوزيع الترتيبي، وكأنها أقل القيم عدداً في السلسلة.
  • na_option='top': يتم وضع القيم المفقودة في قمة الترتيب وتُمنح أعلى الرتب الممكنة.

يوضح المثال البرمجي التالي كيفية تطبيق هذه الخيارات:

df_missing = pd.DataFrame({'Scores': [80, np.nan, 95, 60, np.nan, 75]})

df_missing['Rank_Keep'] = df_missing['Scores'].rank(pct=True, na_option='keep')
df_missing['Rank_Bottom'] = df_missing['Scores'].rank(pct=True, na_option='bottom')
df_missing['Rank_Top'] = df_missing['Scores'].rank(pct=True, na_option='top')

8.2 التأثير الإحصائي للقيم المفقودة على دقة الرتب

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

لذلك، تُشير الممارسات الإحصائية الفضلى إلى ضرورة استخدام na_option='keep' في معظم الحالات، أو إجراء عمليات التنظيف الإحصائي المسبقة (Data Imputation) للبيانات قبل الشروع في حساب الرتب المئوية. تتضمن هذه العمليات استبدال القيم المفقودة بالوسيط الإحصائي (Median) أو تطبيق خوارزميات التنبؤ المتقدمة كخوارزمية الجار الأقرب (K-Nearest Neighbors Imputation)، مع توثيق منهجي شامل لكيفية معالجة البيانات الناقصة في متن التقرير الفني لضمان الشفافية العلمية.

9. تخصيص اتجاه الترتيب: الترتيب التصاعدي والتنازلي

9.1 استخدام المعامل ascending=False

تفترض دالة rank() بصورة افتراضية أن الترتيب تصاعدي (ascending=True)، حيث تُمنح القيمة العددية الأصغر الرتبة الأدنى، بينما تُمنح القيمة الأكبر الرتبة القصوى. ومع ذلك، هناك العديد من السياقات التطبيقية والمهنية التي تتطلب عكساً كاملاً لهذا المنطق الرياضي، بحيث تكون القيمة الأصغر هي الأفضل والأعلى أداءً.

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

df_race = pd.DataFrame({'Time_Seconds': [10.2, 9.8, 11.5, 10.0, 9.5]})

# الزمن الأسرع (الأقل عددياً) يأخذ الرتبة المئوية الأعلى (100%)
df_race['Performance_PR'] = df_race['Time_Seconds'].rank(ascending=False, pct=True) * 100

9.2 مقارنة الاتجاهات في التحليلات الإحصائية

يؤدي تغيير اتجاه الترتيب من التصاعدي إلى التنازلي إلى تحويل التفسير الإحصائي من رتبة مئوية تراكمية اعتيادية إلى رتبة مئوية تراكمية تراجعية. في الترتيب التنازلي، تصبح الرتبة المئوية للعداء الحاصل على 9.5 ثوان هي 100%، مما يعني أن سرعته تتفوق على 100% من المشاركين، بدلاً من أن يُصنف خطأً في القاع الإحصائي بحصوله على 20% لو طُبق الترتيب التصاعدي التقليدي.

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

10. مقارنة دالة rank في بانداز مع دوال مكتبتي SciPy و NumPy

10.1 استخدام دالة scipy.stats.percentileofscore

توفر مكتبة SciPy المتخصصة في الحوسبة العلمية الدالة الشهيرة percentileofscore داخل الموديول scipy.stats. تختلف هذه الدالة في فلسفتها التشغيلية عن بانداز؛ إذ إنها مخصصة لحساب الرتبة المئوية لقيمة واحدة فردية بالنسبة إلى مصفوفة بيانات كاملة، بدلاً من إجراء عملية التحويل المباشر لكامل العمود دفعة واحدة.

تتميز دالة scipy.stats.percentileofscore بمرونتها العالية في تحديد نوع الحساب الدقيق عبر المعامل kind، والذي يقبل الخيارات التالية:

  • kind='rank': يحسب النسبة المئوية للرتبة التقليدية ويطابق خيار average في بانداز.
  • kind='weak': يحسب نسبة القيم التي تقل عن القيمة المحددة أو تساويها مباشرة.
  • kind='strict': يحسب نسبة القيم التي تقل بدقة عن القيمة المحددة دون احتساب القيم المتساوية.
  • kind='mean': يحسب متوسط النسبتين الناتجتين عن weak و strict، وهو الخيار الأكثر دقة في الأدبيات السيكومترية.

يوضح المثال التالي مقارنة الاستخدام:

from scipy import stats

scores = [50, 60, 70, 80, 90, 100]
target_score = 80

# حساب الرتبة المئوية للقيمة 80 باستخدام خيار mean
pr_scipy = stats.percentileofscore(scores, target_score, kind='mean')
print(f"SciPy PR for 80: {pr_scipy}%")

10.2 تقييم الأداء والكفاءة الحاسوبية (Benchmarking)

عند معالجة البيانات الضخمة (Big Data) التي تحتوي على ملايين السجلات، يظهر فارق جوهري في الكفاءة الحوسبية وزمن التنفيذ بين مكتبتي Pandas و SciPy. تم تصميم دالة rank() في بانداز لتكون عملية متجهية بالكامل (Fully Vectorized) تعمل بالتوازي على مستوى المصفوفات بلغة C، مما يجعلها أسرع بمئات المرات مقارنة بتطبيق دالة percentileofscore التكرارية عبر دالة apply() في بايثون.

إذا كان الهدف هو حساب الرتب المئوية لأعمدة كاملة داخل أطر البيانات، فإن الاعتماد على df['col'].rank(pct=True) هو الخيار الأمثل هندسياً من حيث السرعة واستهلاك الذاكرة. أما إذا كان الهدف هو اختبار رتبة مدخلات خارجية جديدة ومفردة ضد معيار إحصائي ثابت ومخزن مسبقاً، فإن دالة SciPy توفر حلاً مباشراً وخفيفاً دون الحاجة لبناء إطار بيانات بانداز كامل.

11. الأخطاء الشائعة واستكشاف المشكلات وإصلاحها (Troubleshooting)

11.1 أخطاء أنواع البيانات وعدم التجانس

من أكثر الأخطاء التقنية شيوعاً أثناء محاولة حساب الرتب المئوية وجود أنواع بيانات غير متجانسة داخل العمود، مثل وجود قيم رقمية تم استيرادها كقيم نصية (Strings) نتيجة وجود مسافات فارغة أو علامات خاصة في ملفات البيانات الأصلية (CSV أو Excel). في هذه الحالة، ستقوم بانداز بترتيب البيانات أبجدياً (Lexicographically) بدلاً من الترتيب الرياضي (فمثلاً ستُعامل القيمة “100” كرتبة أقل من “2” لأن الحرف الأول ‘1’ يسبق ‘2’).

لتفادي وإصلاح هذه المشكلة، يجب تنظيف العمود وتحويله إجبارياً إلى نوع بيانات عددي باستخدام دالة pd.to_numeric مع تفعيل المعامل errors='coerce' لتحويل أي نص غير قابل للتحويل إلى NaN:

# تنظيف وتجهيز العمود العددي
df['Clean_Score'] = pd.to_numeric(df['Raw_Score'], errors='coerce')
df['PR'] = df['Clean_Score'].rank(pct=True)

بالإضافة إلى ذلك، يجب الحذر من تحذير SettingWithCopyWarning الشهير، والذي يحدث عند محاولة إنشاء عمود الرتب على شريحة مقتطعة (Slice) من إطار بيانات بدلاً من العمل على نسخة صريحة (Explicit Copy) باستخدام df.copy().

11.2 الخلط بين مفاهيم الترتيب المئوي المختلفة

يقع بعض الباحثين في خطأ الخلط المفهومي والبرمجي بين دالة الرتبة المئوية rank(pct=True) ودالة المئين الرياضي quantile(). دالة rank(pct=True) تأخذ البيانات كمُدخلات وتُرجع نسباً مئوية كمُخرجات (Input: Data Values $\rightarrow$ Output: Percentiles). بينما دالة quantile() تعمل بالعكس تماماً؛ إذ تأخذ النسبة المئوية كمُدخل وتُرجع القيمة الحدية المقابلة لها في التوزيع (Input: Percentile $\rightarrow$ Output: Cutoff Value).

خطأ شائع آخر يظهر عند محاولة تجميع البيانات الفئوية؛ حيث يلجأ البعض لكتابة df.groupby('Group')['Score'].rank(pct=True) دون استخدام دالة transform()، مما يؤدي إلى حدوث أخطاء برمجية أو إعادة فهرس مصفوفي معقد يعيق عملية دمجه المباشر مع إطار البيانات الأساسي.

12. أفضل الممارسات والتطبيقات المتقدمة في تحليل البيانات الضخمة

12.1 تحسين الأداء وكتابة كود بايثون عالي الكفاءة

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

يمكن تحسين كفاءة الذاكرة بصورة دراماتيكية من خلال تحويل أنواع البيانات العددية المستمرة من الدقة المضاعفة 64-بت (float64) إلى الدقة المفردة 32-بت (float32)، وتحويل الأعمدة النصية الفئوية المتكررة إلى النوع الفئوي (category)، مما يقلل البصمة الذاكرية لإطار البيانات بنسبة تصل إلى 70% دون أي تأثير يذكر على دقة النتائج الإحصائية:

# تحسين أنواع البيانات لتقليل الذاكرة وتسريع الحساب
df['Department'] = df['Department'].astype('category')
df['Performance_Score'] = df['Performance_Score'].astype('float32')

# حساب الرتبة بكفاءة تشغيلية قصوى
df['Optimized_PR'] = (
    df.groupby('Department', observed=True)['Performance_Score']
    .transform('rank', pct=True)
    .astype('float32')
)

12.2 التطبيقات في التحليلات النفسية والسلوكية والاقتصادية

تُشكل الرتب المئوية المحسوبة عبر بانداز حجر الزاوية في مجموعة واسعة من التطبيقات المعاصرة في الاقتصاد السلوكي وذكاء الأعمال والتسويق الرقمي المتقدم. من أبرز هذه التطبيقات: نماذج تصنيف القيمة الدائمة للعملاء (RFM Segmentation)، حيث يتم حساب الرتب المئوية لحداثة الشراء (Recency)، وتكرار الشراء (Frequency)، والقيمة المالية (Monetary Value)، لتقسيم العملاء إلى شرائح دقيقة (مثل شريحة أفضل 1% من كبار العملاء VIP).

في مجال قياس وتجربة المستخدم (User Experience Analytics)، تُستخدم الرتب المئوية لمراقبة أداء واجهات الأنظمة والبرمجيات؛ حيث يتم تقييم سرعة استجابة الخوادم وزمن التحميل من خلال المئين 95 والـ 99، لتحديد متى يعاني المستخدمون الأكثر تضرراً من بطء الخدمة. كما تُعد أداة محورية في المنصات التعليمية المتكيفة (Adaptive Learning Systems) لتقديم تغذية راجعة فورية للطلاب توضح رتبتهم ومستواهم المعرفي مقارنة بأقرانهم على مستوى الدولة أو العالم، مما يسهم في تخصيص مسارات التعلم وتوجيه الدعم الأكاديمي بدقة متناهية.

خاتمة

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

إن إتقان التعامل مع المعاملات المتقدمة لدالة rank()—مثل معالجة التكرارات (Ties)، وإدارة القيم المفقودة (NaNs)، والتحكم في اتجاه الترتيب (Ascending vs Descending)—يُمكّن الباحثين وعلماء البيانات من بناء نماذج تقييمية تتسم بأعلى درجات العدالة المنهجية والموثوقية العلمية. ندعو القارئ إلى تطبيق هذه الأكواد المتقدمة والأنماط المعمارية في مشاريعه التحليلية لضمان استخراج أقصى قيمة تفسيرية ممكنة من البيانات الضخمة المعقدة.

References

  • McKinney, W. (2022). Python for Data Analysis: Data Wrangling with pandas, NumPy, and Jupyter (3rd ed.). O’Reilly Media. https://wesmckinney.com/book/
  • The pandas development team. (2023). pandas.Series.rank — pandas documentation. PyData. https://pandas.pydata.org/docs/reference/api/pandas.Series.rank.html
  • Virtanen, P., Gommers, R., Oliphant, T. E., Haberland, M., Reddy, T., Cournapeau, D., … & SciPy 1.0 Contributors. (2020). SciPy 1.0: Fundamental algorithms for scientific computing in Python. Nature Methods, 17(3), 261-272. https://doi.org/10.1038/s41592-019-0686-2
  • Harris, C. R., Millman, K. J., van der Walt, S. J., Gommers, R., Virtanen, P., Cournapeau, D., … & Oliphant, T. E. (2020). Array programming with NumPy. Nature, 585(7825), 357-362. https://doi.org/10.1038/s41586-020-2649-2
  • Crocker, L., & Algina, J. (2008). Introduction to Classical and Modern Test Theory. Cengage Learning.

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

looti, M. (2026, سبتمبر 2). كيفية حساب الرتبة المئوية في بانداز (مع أمثلة). عرب سايكلوجي. https://arabpsychology.com/how-to-calculate-percentile-rank-in-pandas/
looti, Mohammed. “كيفية حساب الرتبة المئوية في بانداز (مع أمثلة).” عرب سايكلوجي, 2 سبتمبر 2026, https://arabpsychology.com/how-to-calculate-percentile-rank-in-pandas/.
looti, Mohammed. “كيفية حساب الرتبة المئوية في بانداز (مع أمثلة).” عرب سايكلوجي. سبتمبر 2, 2026. https://arabpsychology.com/how-to-calculate-percentile-rank-in-pandas/.