السلاسل الزمنيةتحليل البيانات ببايثونعلم البيانات

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

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

Mohammed looti أكاديمي وباحث متخصص في علم النفس
تاريخ النشر
تمت المراجعة العلمية · د. مروة عبد العظيم · 10 سبتمبر، 2026
مراجعة وتدقيق علمي معتمد تاريخ التدقيق: 10 سبتمبر، 2026
د. مروة عبد العظيم دكتوراه
أستاذة علم النفس جامعة كربلاء
معايير التدقيق والاعتماد السريري

يخضع هذا المحتوى لمعايير ضبط الجودة والتدقيق العلمي والأكاديمي الصارمة في شبكة علم النفس العربي، لضمان صحة المعلومات ودقتها السريرية ومطابقتها لأحدث الأدلة والبراهين الصادرة عن الجمعيات النفسية والطبية المعتمدة (APA / WHO).

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

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

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

1. مقدمة نظرية حول الوسيط المتدحرج في تحليل السلاسل الزمنية

1.1 المفهوم الإحصائي للوسيط المتدحرج

يمثل الوسيط الإحصائي (Median) القيمة التي تفصل النصف الأعلى من عينة البيانات أو التوزيع الاحتمالي عن النصف الأدنى، بحيث يقع 50% من الرصدات دونه و50% فوقه عند ترتيب القيم ترتيباً تصاعدياً أو تنازلياً. وتكمن الميزة الإحصائية الفائقة للوسيط في امتلاكه لما يُعرف في الإحصاء المتين (Robust Statistics) بأعلى “نقطة انهيار” (Breakdown Point) ممكنة لأي مقياس نزعة مركزية، وتصل إلى 50%. هذا يعني أن نصف بيانات العينة تقريباً يجب أن تكون ملوثة بقيم شاذة لانهائية قبل أن تخرج قيمة الوسيط المحسوبة عن النطاق الطبيعي للبيانات، على النقيض التام من المتوسط الحسابي التقليدي (Arithmetic Mean) الذي يمتلك نقطة انهيار تقارب الصفر (0%)؛ حيث تكفي قيمة متطرفة واحدة ذات مقدار هائل لتشويه المتوسط وسحبه بالكامل بعيداً عن مركز الكتلة الإحصائية الحقيقي للبيانات.

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

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

1.2 دور النوافذ المنزلقة في تنقية الإشارات وتحليل البيانات

تعمل تقنية النوافذ المنزلقة (Sliding Windows) في معالجة الإشارات وتحليل السلاسل الزمنية كمرشح تمرير منخفض غير خطي (Non-linear Low-pass Filter). في الواقع العملي، تحتوي السلاسل الزمنية الخام على مزيج من ثلاثة مكونات رئيسية: الاتجاه طويل الأجل (Trend)، والمكون الموسمي أو الدوري (Seasonality)، والضوضاء العشوائية عالية التردد (High-frequency Noise). تهدف النوافذ المنزلقة إلى عزل هذه الضوضاء وتنعيم المسار البياني لإبراز الاتجاه الهيكلي دون التضحية بالخصائص الفيزيائية أو الاقتصادية الأساسية للظاهرة.

تتفوق مرشحات الوسيط المنزلق تفوقاً ملحوظاً على المرشحات الخطية (مثل مرشحات المتوسط المتحرك أو المرشحات الغاوسية) في قدرتها الفريدة على إزالة ما يُعرف بـ “ضوضاء النبضات” (Impulse Noise) أو طفرات القياس الشاذة المؤقتة مع الحفاظ التام على “القفزات الهيكلية” الحقيقية في البيانات (Step Changes). إذا قفزت قراءة حساس حراري فجأة من 20 إلى 80 درجة مئوية واستقرت هناك نتيجة تحول فعلي في النظام، فإن الوسيط المتدحرج ينقل خط الاتجاه بسرعة وحسم إلى المستوى الجديد بمجرد أن تصبح القراءات الجديدة تمثل أغلبية قيم النافذة، دون أن يولد منحنى انتقال بطيئاً ومضللاً كما يفعل المتوسط المتحرك.

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

1.3 مكانة الوسيط المتدحرج في بيئة بايثون لتحليل البيانات

تحتل لغة بايثون موقع الصدارة العالمي في الحوسبة العلمية وهندسة البيانات بفضل منظومتها المتكاملة التي تجمع بين لغة عالية المستوى وسهلة الاستخدام، ومكتبات تنفيذية منخفضة المستوى مكتوبة بالسي (C) والسي بلس بلس والسايثون (Cython). تتصدر مكتبة نمباي (NumPy) وبانداز هذه المنظومة من خلال توفير تراكيب بيانات متجهة (Vectorized Data Structures) تنفذ العمليات الحسابية داخل كتل ذاكرة مدمجة ومتجاورة، مما يلغي تماماً عبء الحلقات التكرارية البطيئة (For-loops) في بايثون الصافية.

يمثل الوسيط المتدحرج داخل إطار عمل بانداز أداة تأسيسية لا غنى عنها في مرحلة هندسة الخصائص (Feature Engineering) لبناء النماذج التنبؤية المتطورة لتعلم الآلة مثل نماذج تعزيز التدرج (Gradient Boosting) والشبكات العصبية المتكررة (RNNs). يوفر حساب الوسيط عبر نوافذ متعددة الأحجام (مثل 7 أيام، 14 يوماً، 30 يوماً) متجهات إحصائية تلتقط وتيرة التغير النسبي، والزخم الحقيقي للسلسلة، ومقاييس التشتت المحلية عند دمجها مع الانحراف المطلق عن الوسيط (MAD).

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

2. البنية التركيبية لدالة rolling() و median() في بانداز

2.1 تحليل الصيغة النحوية الأساسية لدالة rolling

تعتمد مكتبة بانداز في تطبيق العمليات المتدحرجة على معمارية معالجة مصفوفية متطورة، حيث تبدأ العملية باستدعاء دالة rolling() على كائن من نوع Series أو DataFrame، مما يؤدي إلى إنشاء كائن تجميعي متخصص ينتمي إلى الفئة pandas.core.window.rolling.Rolling. لا تقوم هذه الدالة بإجراء الحساب الإحصائي الفعلي فور استدعائها، بل تؤسس البنية المنطقية ومحددات النافذة المكانية والزمنية وفق ما يُعرف في هندسة البرمجيات بالتقييم الكسول (Lazy Evaluation)، وتنتظر استدعاء دالة تجميعية لاحقة مثل median() لتنفيذ الحسابات الرياضية.

تتطلب الصيغة النحوية الأساسية للدالة تمرير المعامل المحوري window، والذي يحدد حجم النافذة المنزلقة. يمكن لهذا المعامل أن يأخذ شكلاً من شكلين رئيسيين: إما عدداً صحيحاً موجباً (Integer) يعبر عن عدد الصفوف المتتالية التي تشملها النافذة، أو إزاحة زمنية (Time-delta / Offset) تُمرر كسلسلة نصية (مثل '3D' لثلاثة أيام أو '2h' لساعتين) بشرط أن يكون فهرس إطار البيانات من النوع الزمني DatetimeIndex. بمجرد ربط دالة median() بكائن النافذة المتولد، ترجع العملية كائناً من نفس نوع المدخلات الأصلية يحافظ على الفهرس والترتيب البنيوي للبيانات.

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

2.2 المعاملات الجوهرية المؤثرة في سلوك الدالة

تحتوي دالة rolling() على حزمة من المعاملات المتقدمة التي تحدد بدقة متناهية سلوك النافذة عند الحواف وفي الحالات الحدية، وهي كالآتي:

  • معامل min_periods: يحدد هذا المعامل، الذي يقبل قيمة عددية صحيحة، الحد الأدنى من المشاهدات الصالحة (غير المفقودة) الواجب توافرها داخل النافذة لإصدار نتيجة عددية للوسيط. إذا لم يتم تحديده صراحة، فإنه يأخذ افتراضياً قيمة مساوية لحجم النافذة window إذا كانت النافذة محددة بعدد الصفوف، مما يتسبب في ظهور قيم مفقودة (NaN) في بداية السلسلة إلى حين اكتمال حجم النافذة.
  • معامل center: وهو معامل منطقي ثنائي (Boolean) يأخذ القيمة False بصورة افتراضية. عند ضبطه على True، تقوم بانداز بتغيير موضع إسناد القيمة المحسوبة لتكون في منتصف النافذة تماماً بدلاً من حافتها اليمنى، مما يلغي الإزاحة الطورية والتأخر الزمني في الرسوم البيانية الاستعادية.
  • معامل closed: يتحكم هذا المعامل في شمولية أو استبعاد النقاط الطرفية للنافذة، وتحديداً عند استخدام الفهارس الزمنية. يقبل المعامل أربعة خيارات نصية رئيسية: 'right' (وهو الافتراضي، حيث يشمل الحد الأيمن ويستبعد الأيسر)، أو 'left' (يستبعد الحد الأيمن الحالي لمنع تسرب البيانات)، أو 'both' (يشمل كلا الطرفين)، أو 'neither' (يستبعد كلا الطرفين).
  • معامل win_type: يتيح هذا المعامل تطبيق نوافذ تصفية متقدمة ذات أوزان متدرجة، مستعارة من مكتبة سايباي (SciPy) لمعالجة الإشارات، مثل نوافذ 'hamming' أو 'blackman' أو 'gaussian'. ومع ذلك، تجدر الإشارة الرياضية إلى أن معظم نوافذ الأوزان تنطبق بشكل أساسي على المتوسطات المرجحة وتتعطل دلالتها عند حساب الوسيط الذي يعتمد بنيوياً على الترتيب الرتبي المجرد للقيم بدلاً من الجمع الوزني المباشر.

2.3 كيفية عمل الخوارزمية داخلياً داخل إطار بانداز

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

تعتمد خوارزميات بانداز المنفذة بلغة C ومكتبات Cython على استراتيجيات فرز وانتقاء عالية الكفاءة. في النوافذ الصغيرة، يمكن استخدام خوارزميات التحديد السريع (Quickselect) أو الفرز الجزئي للعثور على إحصائية الترتيب المستهدفة. أما في النوافذ الأكبر حجماً، تُستخدم هياكل بيانات مثل “الأكوام المزدوجة” (Dual Heaps) أو أشجار البحث الثنائية المتوازنة ذات الرتب المفروزة، حيث يُحافظ النظام على كومة عليا وكومة سفلى متوازنتين لاستخراج الوسيط في وقت لوغاريتمي سريع دون الحاجة لإعادة فرز جميع عناصر النافذة من البداية عند كل خطوة.

تضمن طبقة Cython التحويل الفوري لبيانات أعمدة بانداز إلى مؤشرات ذاكرة متصلة بلغة السي (C-contiguous Arrays)، مما يتيح للمعالج الاستفادة من التخزين المؤقت في المسجلات السريعة (CPU Caches) وتفادي إنشاء نسخ وسيطة للبيانات، وهو ما يحقق أقصى درجات التسريع الحسابي الموجه لعمليات الانزلاق والفرز الرتبي المتكررة.

3. تجهيز بيئة العمل وإنشاء إطار البيانات الأولي

3.1 استيراد المكتبات وتهيئة البيئة البرمجية

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

إلى جانب الاستيراد النمطي، يُفضل ضبط خيارات العرض العامة داخل بيئات الحوسبة التفاعلية مثل Jupyter Notebooks أو Google Colab، وذلك لضمان ظهور كافة الأعمدة والصفوف دون تقطيع أو اختصار مشوه، مما يسهل تتبع النتائج ومقارنتها بدقة تحليلية واضحة:

يتم تنفيذ الاستيراد وتهيئة الخيارات وفق النسق البرمجي الآتي:

import pandas as pd
import numpy as np

# ضبط خيارات العرض التنسيقي في بانداز
pd.set_option('display.max_columns', 10)
pd.set_option('display.max_rows', 20)
pd.set_option('display.float_format', lambda x: '%.3f' % x)

# التحقق من إصدار بانداز الحالي
print("Pandas Version:", pd.__version__)

3.2 بناء مجموعة بيانات المبيعات والمؤشرات المستهدفة

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

يتم إنشاء إطار البيانات وتحديد بياناته من خلال الشيفرة التالية:

# إنشاء إطار البيانات الأولي للتحليل التسلسلي
data = {
    'month': pd.date_range(start='2024-01-01', periods=12, freq='MS'),
    'leads': [120, 135, 128, 142, 190, 155, 148, 162, 158, 310, 170, 165],
    'sales': [45.2, 48.0, 46.5, 52.1, 85.0, 56.4, 54.2, 59.0, 58.1, 120.5, 62.0, 61.3],
    'cac': [15.0, 14.2, 14.8, 13.9, 22.5, 15.1, 14.9, 14.5, 14.6, 28.0, 15.2, 15.0]
}

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

يكشف الفحص الأولي للبيانات باستخدام df.info() وdf.describe() عن وجود تشوهات واضحة ناتجة عن طفرات بيعية غير اعتيادية في الشهر الخامس (مايو) والشهر العاشر (أكتوبر)، حيث ارتفعت المبيعات إلى 85.0 و120.5 ألف على التوالي نتيجة صفقات استثنائية فردية. هذا التباين الشديد بين المتوسط الحسابي والانحراف المعياري في التقرير الوصفي يجعل هذه المجموعة بيئة اختبار مثالية لقياس تفوق الوسيط المتدحرج على المتوسط المتدحرج.

3.3 إعداد الفهارس والتأكد من ترتيب السلسلة الزمنية

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

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

# التأكد من ترتيب السلسلة ترتيباً تصاعدياً صارماً
df = df.sort_values(by='month', ascending=True).reset_index(drop=True)

# فحص الفروق الزمنية للتحقق من عدم وجود فجوات في الترتيب
time_diffs = df['month'].diff()
print("فروق الفترات الزمنية بين الرصدات المتتالية:")
print(time_diffs.value_counts())

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

4. حساب الوسيط المتدحرج لنافذة ثابتة من ثلاث فترات

4.1 تطبيق الكود الأساسي على عمود فردي

لحساب الوسيط المتدحرج لنافذة تتألف من ثلاث فترات متتالية، نقوم باستدعاء الدالة rolling(window=3) مباشرة على عمود المبيعات df['sales'] متبوعة بالدالة التجميعية median(). تُسند النتائج المستخرجة إلى عمود جديد داخل نفس إطار البيانات باسم sales_rolling_med_3 لإجراء المقارنات المباشرة جنباً إلى جنب مع البيانات الأصلية:

# تطبيق الوسيط المتدحرج لنافذة ثلاثية الفترات
df['sales_rolling_med_3'] = df['sales'].rolling(window=3).median()

# عرض النتائج لمقارنة السلسلة الأصلية بالمحسوبة
print(df[['month', 'sales', 'sales_rolling_med_3']])

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

  • الصف الأول (يناير): قيمة المبيعات 45.2. تتطلب النافذة 3 فترات ولكن المتاح قيمة واحدة فقط، والنتيجة الحسابية هي NaN.
  • الصف الثاني (فبراير): تتوفر قيمتان هما [45.2, 48.0]. النافذة ما زالت غير مكتملة، والنتيجة تظل NaN.
  • الصف الثالث (مارس): تكتمل النافذة الثلاثية بالقيم [45.2, 48.0, 46.5]. عند فرز هذه القيم تصاعدياً تصبح: [45.2, 46.5, 48.0]. القيمة الوسطى ذات الترتيب الثاني هي 46.5، وهي القيمة الأولى المسجلة في العمود المتدحرج.
  • الصف الرابع (أبريل): تنزلق النافذة خطوة واحدة للأمام لتسقط قيمة يناير وتصبح عناصر النافذة [48.0, 46.5, 52.1]. بعد الفرز: [46.5, 48.0, 52.1]، ويكون الوسيط هو 48.0.

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

4.2 تفسير القيم الفارغة الأولية (NaN)

يمثل ظهور القيم المفقودة المسماة “ليست رقماً” (NaN – Not a Number) في بداية الأعمدة المتدحرجة سلوكاً رياضياً حتمياً ومنطقياً متأصلاً في طبيعة النوافذ المتدحرجة ذات الأحجام الثابتة. عند تحديد window=3 مع الإعدادات الافتراضية، تشترط خوارزمية بانداز وجود ثلاث رصدات فعلية لإنشاء التوزيع التكراري المصغر الخاص بالنافذة، مما يجعل من المستحيل حساب وسيط ثلاثي للصفين الأول والثاني لعدم اكتمال حجم العينة الإحصائي المستهدف.

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

4.3 الحساب المتزامن على أعمدة رقمية متعددة

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

# تحديد قائمة الأعمدة المستهدفة بالتحليل المتدحرج
target_cols = ['leads', 'sales', 'cac']

# حساب الوسيط المتدحرج لجميع الأعمدة دفعة واحدة
rolling_medians = df[target_cols].rolling(window=3).median()

# إعادة تسمية الأعمدة المشتقة ديناميكياً لتجنب تداخل التسميات
rolling_medians = rolling_medians.add_suffix('_roll_med_3')

# دمج النتائج الجديدة مع إطار البيانات الأصلي
df_combined = pd.concat([df, rolling_medians], axis=1)
print(df_combined.head(6))

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

5. التعامل مع القيم المفقودة وضبط معامل min_periods

5.1 تخفيف قيود حجم النافذة باستخدام min_periods

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

عند تعيين min_periods=1 لنافذة حجمها 3، تصبح دالة بانداز قادرة على حساب الوسيط ابتداءً من الصف الأول تماماً:

# تطبيق الوسيط المتدحرج مع السماح بالحساب بدءاً من رصدة واحدة
df['sales_med_minp1'] = df['sales'].rolling(window=3, min_periods=1).median()
print(df[['sales', 'sales_rolling_med_3', 'sales_med_minp1']].head(4))

في هذه الحالة، يكون وسيط الصف الأول مساوياً لقيمة الصف الأول الفردية نفسها (45.2). وفي الصف الثاني، تتوفر قيمتان [45.2, 48.0]، فتحسب الخوارزمية الوسيط بينهما عن طريق جمع القيمتين وقسمتهما على اثنين ليصبح الناتج (46.6). وعند الوصول إلى الصف الثالث، تصبح النافذة ثلاثية مكتملة وتعود الحسابات إلى وتيرتها القياسية. تتيح هذه المرونة تغطية كامل السلسلة دون قيم فارغة، ولكن ينبغي الانتباه إلى أن الدقة الإحصائية ومستوى التنعيم في الصفوف الأولى يكونان أقل من بقية السلسلة نظراً لصغر حجم العينة الفعلي المستخدم في تلك النقاط.

5.2 معالجة وجود قيم مفقودة مسبقة داخل البيانات

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

إذا انخفض عدد القيم الصالحة داخل النافذة عن حد min_periods، تُنتج الخوارزمية قيمة NaN في موضع الحساب. يضع هذا السلوك المحلل أمام خيارين منهجيين:

  • الملء المسبق (Pre-imputation): استخدام تقنيات التمرير للأمام ffill() أو التمرير للخلف bfill() أو الاستيفاء الخطي interpolate() لسد الفجوات قبل التدحرج. يؤدي هذا الخيار إلى استقرار حجم النافذة، ولكنه قد يسبب انحيازاً غير مرغوب فيه في الوسيط إذا تم تكرار قيمة شاذة عدة مرات.
  • الاحتفاظ بالفجوات (Gap Preservation): ترك القيم المفقودة كما هي والاعتماد على مرونة الوسيط وmin_periods لتجاوزها. يضمن هذا النهج عدم إدخال بيانات مصطنعة في السلسلة، مع الحفاظ على الأمانة الإحصائية للقياسات الحقيقية.

5.3 تقييم جودة السلسلة الناتجة بعد معالجة الفقد

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

يتم الفحص المنهجي لاكتمال المتجه الإحصائي ومقارنة خصائصه من خلال عمليات التحقق الرياضية التالية:

# التحقق من خلو الأعمدة الناتجة من أي قيم مفقودة
null_summary = df[['sales_rolling_med_3', 'sales_med_minp1']].isna().sum()
print("عدد القيم المفقودة في كل استراتيجية:")
print(null_summary)

# فحص الفروق النسبية بين استراتيجية الانتظار واستراتيجية التخفيف
diff = df['sales_med_minp1'] - df['sales_rolling_med_3']
print("فروق التقدير الناتجة عن تخفيف قيود min_periods:")
print(diff.dropna())

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

6. تخصيص محاذاة النوافذ: النوافذ المتمركزة والمتقدمة

6.1 آلية عمل النوافذ المتمركزة (Centered Windows)

في الوضع الافتراضي لبانداز، تنتهي النافذة المنزلقة عند الملاحظة الحالية، أي أن قيمة الوسيط المحسوبة عند اللحظة الزمنية $t$ تعتمد كلياً على المشاهدات الواقعة في النطاق $[t – window + 1, t]$. يُعرف هذا النمط بالمحاذاة الخلفية أو المحاذاة لليمين، وينتج عنه حتماً ما يُسمى بـ “التأخر الزمني” أو إزاحة الطور (Phase Lag) في المنحنى البياني، حيث تظهر التغيرات في السلسلة المنعمة متأخرة زمنياً بعد حدوثها الفعلي في السلسلة الأصلية.

للقضاء على هذا التأخر وإجراء تنعيم متماثل يعبر عن منتصف النطاق بدقة، توفر بانداز المعامل center=True. عند تفعيل هذا المعامل، تُعاد هيكلة النافذة لتصبح متمركزة حول الملاحظة الحالية، بحيث تمتد النافذة لتشمل نقاطاً متساوية (أو شبه متساوية) تسبق الملاحظة الحالية وتليها، أي في النطاق الحسابي $[t – lfloor window/2 rfloor, t + lfloor window/2 rfloor]$.

# تطبيق الوسيط المتدحرج المتمركز حول الملاحظة
df['sales_med_centered'] = df['sales'].rolling(window=3, center=True).median()
print(df[['sales', 'sales_rolling_med_3', 'sales_med_centered']].head(5))

يعد التوسيط حلاً رياضياً مثالياً في التحليل الارتجاعي التاريخي (Retrospective Analysis) وتنقية الإشارات المسجلة مسبقاً؛ لأنه يقدم خط اتجاه متطابقاً تماماً مع قمم وقيعان السلسلة الأصلية دون أي زحزحة مكانية. ومع ذلك، يُحظر تماماً استخدام النوافذ المتمركزة في تطبيقات التنبؤ الحي والآني (Real-time Forecasting)؛ لأن حساب الوسيط المتمركز في اللحظة الراهنة يتطلب معرفة قيم مستقبلية لم تقع بعد، وهو ما يستحيل تحقيقه عملياً إلا من خلال الوقوع في خطأ تسرب البيانات الكارثي.

6.2 التعامل مع النوافذ ذات الأطوال الزوجية والفردية

يرتبط السلوك الحسابي للنوافذ المتمركزة ارتباطاً وثيقاً بالطبيعة الرياضية لحجم النافذة، وما إذا كان عدداً فردياً أو زوجياً. عندما يكون حجم النافذة عدداً فردياً (مثل $3$، $5$، $7$)، تتحدد النقطة المركزية بدقة مطلقة وتناظر تام؛ فالنافذة ذات الحجم 3 تتمركز عند النقطة الحالية وتأخذ نقطة سابقة واحدة ونقطة لاحقة واحدة، مما يجعل المفهوم الهندسي للمركز بديهياً ولا لبس فيه.

أما عندما يكون حجم النافذة عدداً زوجياً (مثل $4$ أو $6$)، ينعدم وجود صف وسيط منفرد يمثل المركز الهندسي الصارم للنافذة. في هذه الحالة، تطبق بانداز قاعدة موحدة تسند بموجبها المركز إلى الموضع الأيسر من المنتصف النظري، مستخدمة الصيغة الفهرسية: offset = (window - 1) // 2. يوضح الجدول التالي مقارنة السلوك الهيكلي بين الأطوال الفردية والزوجية:

حجم النافذة طبيعة الحجم المسافة السابقة (Lag) المسافة اللاحقة (Lead) طريقة حساب الوسيط داخل النافذة
3 فردي 1 صف 1 صف القيمة الوسطى ذات الترتيب الثاني مباشرة
4 زوجي 1 صف 2 صفوف متوسط القيمتين المركزيتين بعد الفرز
5 فردي 2 صفوف 2 صفوف القيمة الوسطى ذات الترتيب الثالث مباشرة

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

6.3 ضبط المعامل closed وتحديد شمولية الأطراف

يتيح المعامل closed التحكم في الحدود الرياضية للنافذة المغلقة والمفتوحة، وهو معامل يكتسب أهميته القصوى عند التعامل مع الفهارس الزمنية المتصلة لمنع حدوث التداخلات غير المرغوبة. تدعم بانداز أربعة خيارات أساسية تحدد أطراف الفترة المغلقة $[a, b]$ على النحو الآتي:

  • الخيار 'right': يُعد هذا الخيار هو الإعداد الافتراضي في مكتبة بانداز؛ حيث تكون الفترة نصف مفتوحة من اليسار ومغلقة من اليمين $(t – window, t]$، مما يعني شمول الرصدة الحالية في الحساب واستبعاد الرصدة الواقعة عند أقصى الحافة السابقة.
  • الخيار 'left': يجعل الفترة مغلقة من اليسار ومفتوحة من اليمين $[t – window, t)$؛ حيث تُستبعد الرصدة الحالية تماماً من الحساب التجميعي. تكتسب هذه الميزة أهمية استثنائية في بناء النماذج التنبؤية لهندسة ميزات السلاسل الزمنية، حيث تضمن أن الوسيط المحسوب عند اللحظة $t$ يقتصر فقط على الماضي الصرف دون أن يحتوي على قيمة اللحظة الحالية، مما يقضي جذرياً على مخاطر تسرب البيانات التنبؤية.
  • الخيار 'both': يجعل النافذة مغلقة من الطرفين $[t – window, t]$، بحيث تُدرج نقاط النهاية كلياً داخل العينة المحسوبة.
  • الخيار 'neither': يجعل النافذة مفتوحة كلياً من الجانبين $(t – window, t)$، مستبعداً النقطة الحالية والنقطة السابقة المقابلة للحافة القصوى.

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

7. حساب الوسيط المتدحرج المستند إلى التواريخ والأزمنة

7.1 تحويل الفهرس إلى DatetimeIndex لتمكين النوافذ الزمنية

في العديد من البيئات التشغيلية والأنظمة الحية، لا تتدفق القياسات بمعدلات متجانسة تفصلها أعداد صفوف متساوية، بل تصل في أوقات متباعدة وغير متوقعة. لإجراء تدحرج إحصائي مستند إلى فترات زمنية حقيقية (مثل “وسيط آخر 30 يوماً” أو “وسيط آخر 6 ساعات”)، يجب أولاً تحويل الفهرس التشغيلي لإطار البيانات إلى فهرس زمني رسمي من نوع DatetimeIndex.

تتم هذه العملية عبر استخدام الدالة الموجهة pd.to_datetime() لتحويل العمود الزمني النصي إلى كائنات زمنية قياسية، ثم إسناد الناتج كفهرس رسمي للإطار باستخدام set_index()، مع ضرورة فرز الفهرس الزمني تصاعدياً عبر sort_index() كشرط إلزامي تفرضه بانداز لتشغيل النوافذ المعتمدة على الفترات الزمنية:

# نسخ البيانات وإعداد الفهرس الزمني المتخصص
df_time = df.copy()
df_time['month'] = pd.to_datetime(df_time['month'])
df_time = df_time.set_index('month').sort_index()

# التحقق من بنية الفهرس الزمني الجديد
print(df_time.index)

يمكّن هذا الفهرس الزمني المتخصص إطار البيانات من فهم ومعالجة السلاسل النصية المعبرة عن الفترات الزمنية مثل '7D' (سبعة أيام)، أو '30D' (ثلاثون يوماً)، أو '12h' (اثنتا عشرة ساعة)، وتفسيرها كأبعاد فيزيائية حقيقية على المحور الزمني بدلاً من مجرد تعداد للصفوف المتتالية.

7.2 الفروق بين النوافذ المبنية على عدد الصفوف والنوافذ المبنية على المدد الزمنية

يكمن الفرق الجوهري بين النوافذ المبنية على عدد الصفوف (Row-based Windows) والنوافذ المبنية على المدد الزمنية (Offset-based Windows) في كيفية تعامل النظام مع الفترات غير المنتظمة والبيانات المفقودة في التقويم. يوضح التحليل المقارن التالي الأثر الميداني لكل نموذج:

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

في المقابل، عندما نستخدم نافذة زمنية مثل rolling(window='90D')، تقوم بانداز بفحص الفهرس الزمني لكل صف وتتحرك إلى الوراء مسافة زمنية قدرها تسعون يوماً فيزيائياً من لحظة الطابع الزمني الحالي. إذا لم تجد الخوارزمية في تلك الفترة الزمنية إلا قراءة واحدة، فإنها تحسب الوسيط لتلك القراءة الفردية فقط (بافتراض ضبط min_periods=1)، وإذا وجدت مائة قراءة جرت في تلك الأيام التسعين، فإنها تحسب الوسيط لجميع تلك القراءات المائة. تحافظ هذه المنهجية على الترابط الفيزيائي السليم للظواهر المستمرة كتقلبات درجات الحرارة أو تدفقات السيولة المالية في البورصات التي تتوقف في عطلات نهاية الأسبوع.

7.3 التعامل مع السلاسل الزمنية غير المنتظمة (Irregular Time Series)

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

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

المنهج الثاني: التدحرج المباشر على الإزاحة الزمنية: يتمثل في تطبيق دالة rolling('30D') مباشرة على السلسلة غير المنتظمة بدون إعادة تشكيل:

# تطبيق الوسيط المتدحرج مباشرة عبر نافذة زمنية قدرها 60 يوماً
df_time['sales_roll_60d'] = df_time['sales'].rolling(window='60D').median()
print(df_time[['sales', 'sales_roll_60d']])

يتعامل هذا المنهج المباشر بكفاءة فائقة مع كثافة العينات المتغيرة؛ ففي فترات النشاط المكثف يتوسع حجم العينة داخل النافذة مما يزيد من دقة الوسيط ونعومته، وفي فترات الركود تتقلص العينة تلقائياً دون الحاجة لتوليد بيانات وهمية، مما يجعله الخيار الأمثل لتحليل السجلات الحدثية المتقطعة (Event-driven Logs).

8. تطبيق الوسيط المتدحرج على مجموعات البيانات المصنفة بواسطة groupby

8.1 دمج دالة rolling() مع groupby() لعزل الكيانات

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

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

# بناء إطار بيانات متعدد الفئات لاختبار التصنيف
panel_data = {
    'store': ['Store_A']*6 + ['Store_B']*6,
    'date': pd.date_range('2024-01-01', periods=6, freq='M').tolist() * 2,
    'revenue': [100, 105, 110, 150, 115, 120, 200, 210, 290, 215, 220, 225]
}
df_panel = pd.DataFrame(panel_data)

# حساب الوسيط المتدحرج مع عزل الكيانات لكل متجر
grouped_rolling = df_panel.groupby('store')['revenue'].rolling(window=3).median()
print(grouped_rolling)

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

8.2 إعادة هيكلة الفهارس ومحاذاة المخرجات مع إطار البيانات الأصلي

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

لتجاوز هذا التحدي، توجد طريقتان قياسيتان لإعادة هيكلة ومحاذاة البيانات:

  • الطريقة الأولى: استخدام reset_index(): يتم تفكيك الفهرس المتعدد عبر إسقاط مستوى الفئة واسترجاع الفهرس الفردي الأصلي، ومن ثم تعيين السلسلة الناتجة:
    # تفكيك الفهرس المتعدد ومحاذاة البيانات مع الجدول الأصلي
    df_panel['rolling_rev'] = grouped_rolling.reset_index(level=0, drop=True)
    print(df_panel)
    
  • الطريقة الثانية: استخدام transform(): يُعد استخدام دالة التحويل transform() بديلاً بالغ الذكاء والأناقة؛ حيث تطبق عملية الحساب التجميعي داخل كل مجموعة مع إرجاع مصفوفة تحمل ذات أبعاد وفهرس إطار البيانات الأصلي مباشرة دون الحاجة للتعامل مع الفهرس المزدوج إطلاقاً:
    # استخدام دالة transform لتجنب مشاكل الفهرس المتعدد تماماً
    df_panel['rev_med_trans'] = df_panel.groupby('store')['revenue'].transform(
        lambda s: s.rolling(window=3).median()
    )
    

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

8.3 إدارة الفئات ذات السلاسل القصيرة داخل المجموعات

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

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

9. مقارنة الوسيط المتدحرج بالمتوسط المتدحرج ودوره في معالجة الشذوذ

9.1 تحليل الحساسية تجاه القيم الشاذة والمتطرفة (Outliers)

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

# حساب المتوسط المتدحرج والوسيط المتدحرج جنباً إلى جنب
df_comp = df[['month', 'sales']].copy()
df_comp['rolling_mean'] = df_comp['sales'].rolling(window=3).mean()
df_comp['rolling_median'] = df_comp['sales'].rolling(window=3).median()

# عرض الفجوة الناتجة بين المقياسين أثناء الطفرة البيعية
print(df_comp.iloc[3:8])

توضح مخرجات المقارنة في الشهر الخامس (الذي شهد قفزة إلى 85.0 ألف) فارقاً مذهلاً في السلوك الرياضي؛ حيث قفز المتوسط المتدحرج مباشرة من 48.8 إلى 61.2 ألف، واستمر مرتفعاً بشكل مضلل في الأشهر التالية متأثراً بوجود تلك القيمة المفردة داخل النافذة. في المقابل، تحرك الوسيط المتدحرج بهدوء بالغ من 48.0 إلى 56.4 ألف فقط، معبراً عن القيمة المركزية الحقيقية للنافذة، ثم عاد واستقر عند 56.4 في الشهر التالي دون أن يجر السلسلة خلف الارتفاع المؤقت.

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

9.2 المفاضلة الحسابية والدلالية بين المقياسين

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

وجه المقارنة الوسيط المتدحرج (Rolling Median) المتوسط المتدحرج (Rolling Mean)
الحساسية للقيم الشاذة شديد المقاومة والمتانة (نقطة الانهيار 50%) شديد الحساسية والهشاشة (نقطة الانهيار 0%)
الحفاظ على المجاميع الكلية لا يحفظ المجموع؛ مجموع الأوساط لا يساوي مجموع الأصل يحفظ المجموع الرياضي بدقة تامة للمحاسبة
التكلفة الحوسبية أعلى نسبياً (تتطلب الفرز أو هياكل بيانات رتبية) منخفضة جداً تعتمد على المجموع التراكمي في وقت ثابت $O(1)$
طبيعة الاستجابة للقفزات استجابة عتبية فورية تحافظ على الحدود الصريحة تنعيم تدريجي ناعم يولد منحنيات انتقال ممتدة
السيناريو الأنسب للاستخدام السلاسل الصاخبة، النظم المالية، بيانات الحساسات الحيوية المحاسبة المالية، توازن الطاقة، التوزيعات الطبيعية النقية

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

9.3 كشف الشذوذ باستخدام الفجوة بين الوسيط والمتوسط المتدحرج

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

لتطوير هذه الآلية بصورة أكثر انضباطاً، يُستخدم مقياس “الانحراف المطلق عن الوسيط المتدحرج” (Rolling Median Absolute Deviation – MAD)، والذي يمثل البديل المتين للانحراف المعياري التقليدي. يتم حساب هذا المقياس من خلال أخذ وسيط الانحرافات المطلقة عن الوسيط المحلي، ومن ثم بناء نطاقات ديناميكية عليا وسفلى تكشف أي قراءة تخرج عن حدود التذبذب الطبيعي المسموح به:

# حساب الوسيط المتدحرج والانحراف المطلق المتدحرج
rolling_med = df['sales'].rolling(window=3).median()
abs_deviation = (df['sales'] - rolling_med).abs()
rolling_mad = abs_deviation.rolling(window=3).median()

# بناء عتبة ديناميكية لكشف القيم الشاذة (معامل قياسي 1.4826 للتوزيع الطبيعي)
mad_threshold = 1.4826 * rolling_mad
anomaly_flag = (df['sales'] - rolling_med).abs() > (2 * mad_threshold)

df['is_anomaly'] = anomaly_flag
print(df[['month', 'sales', 'is_anomaly']])

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

10. التطبيقات العملية لتحليل المقاييس والبيانات السلوكية والزمنية

10.1 تحليل القياسات السلوكية ومؤشرات الأداء المستمرة

تعتمد منصات البرمجيات كخدمة (SaaS) والتطبيقات السحابية على تحليل متواصل لمؤشرات زمن استجابة الخوادم (Server Latency)، وأوقات تحميل الصفحات، وسرعة تفاعل المستخدمين عبر الجلسات المتتالية. تمتاز هذه البيانات بظهور طفرات مؤقتة عنيفة تنتج عن عمليات الصيانة الدورية المجدولة أو التباطؤ المؤقت في شبكات الاتصال، وهي طفرات لا تعكس بأي حال من الأحوال تجربة الاستخدام العامة للغالبية الساحقة من العملاء.

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

ينطبق نفس المفهوم بدقة على قياسات مؤشرات رضا العملاء اللحظية (Customer Satisfaction Scores – CSAT) المجمعة عبر واجهات التفاعل الرقمية؛ حيث يساعد الوسيط المتدحرج في امتصاص ردود الفعل الانفعالية الحادة الناتجة عن مشكلات تقنية مؤقتة، وإبراز التحول الحقيقي والمستقر في المزاج العام لجمهور المنصة على المدى الطويل.

10.2 تحليل اتجاهات المبيعات والطلب التجاري

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

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

10.3 التمثيل البياني المتقدم للمقارنة بين الاتجاه والبيانات الخام

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

يتم تنفيذ الكود البرمجي لإنشاء المخطط البياني المقارن على النحو التالي:

import matplotlib.pyplot as plt
import seaborn as sns

# ضبط النمط الجمالي للمخطط
sns.set_theme(style="whitegrid")
plt.figure(figsize=(12, 6))

# رسم البيانات الأصلية كنقاط متفرقة وخط خفيف
plt.plot(df['month'], df['sales'], marker='o', color='#95a5a6', 
         linestyle='--', alpha=0.7, label='المبيعات الفعلية الخام (Sales)')

# رسم خط الوسيط المتدحرج لإبراز الاتجاه المتين
plt.plot(df['month'], df['sales_med_minp1'], marker='s', color='#2c3e50', 
         linewidth=2.5, label='الوسيط المتدحرج (Rolling Median - Window=3)')

# تمييز النقاط الشاذة لتوضيح دور الوسيط في مقاومتها
plt.axvspan(pd.to_datetime('2024-05-01'), pd.to_datetime('2024-05-02'), 
            color='#e74c3c', alpha=0.2, label='طفرة بيعية معزولة')

# ضبط العناوين والمحاور
plt.title('تحليل اتجاه المبيعات باستخدام الوسيط المتدحرج في بانداز', fontsize=14, fontweight='bold')
plt.xlabel('التاريخ (الشهر)', fontsize=12)
plt.ylabel('حجم المبيعات (بالآلاف)', fontsize=12)
plt.legend(loc='upper left', frameon=True)
plt.tight_layout()

# حفظ الشكل بدقة عالية للتقارير
# plt.savefig('rolling_median_trend.png', dpi=300)

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

11. تحسين الأداء الحسابي والتعامل مع مجموعات البيانات الضخمة

11.1 التعقيد الحسابي لعملية الفرز المتحرك

يمثل التعامل مع مجموعات البيانات الضخمة (Big Data) التي تحتوي على ملايين أو عشرات الملايين من السجلات الزمنية تحدياً حوسبياً كبيراً عند تطبيق النوافذ المتدحرجة؛ نظراً للاختلاف الجوهري في التعقيد الحسابي (Computational Complexity) بين الإحصائيات الخطية والإحصائيات الرتبية. فبينما يستغرق حساب المتوسط المتدحرج تعقيداً زمنياً خطياً إجمالياً قدره $O(N)$ عبر السلسلة بأكملها، فإن الحساب البسيط للوسيط يتطلب فرز محتويات كل نافذة ذات الحجم $K$، مما يرفع التعقيد النظري الساذج إلى $O(N \cdot K \log K)$.

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

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

11.2 استخدام محركات التسريع مثل Numba مع دالة rolling

قدمت الإصدارات الحديثة من مكتبة بانداز ميزة ثورية تتمثل في إمكانية تمرير محرك التحويل البرمجي اللحظي Numba مباشرة داخل دالة النوافذ المتدحرجة عبر المعامل engine='numba'. يقوم محرك Numba بترجمة شفرات بايثون القياسية إلى كود آلي فائق السرعة بلغة الآلة (LLVM Machine Code) يتم تنفيذه مباشرة على المعالج متجاوزاً مفسر بايثون وقفل المفسر العام (GIL).

يتيح هذا المحرك كتابة دوال تجميعية مخصصة للوسيط وتنفيذها بسرعات تقارب البرمجة المباشرة بلغة السي الخالصة:

# تطبيق التسريع باستخدام محرك Numba عبر بانداز
# يتطلب تثبيت مكتبة numba في البيئة البرمجية
try:
    fast_rolling_median = df['sales'].rolling(
        window=3, 
        engine='numba', 
        engine_kwargs={'nopython': True, 'nogil': True}
    ).median()
    print("تم تنفيذ الحساب المسرع بنجاح عبر محرك Numba")
except (ImportError, Exception) as e:
    print("محرك Numba غير متاح، يتم استخدام المحرك الافتراضي:", e)

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

11.3 المعالجة المتوازية وتقنيات تقسيم البيانات (Chunking)

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

تتكفل مكتبة Dask بحل هذه المعضلة الرياضية والهندسية تلقائياً من خلال مفهوم “مناطق التداخل المتدحرجة” (Overlapping Chunks)؛ حيث تحتفظ الخوارزمية بهامش أمان من البيانات السابقة مساوٍ لحجم النافذة $K$ عند توزيع أجزاء السلسلة على خيوط المعالجة المتعددة:

# مثال مفاهيمي لتطبيق النوافذ المتدحرجة الموزعة باستخدام Dask
# import dask.dataframe as dd
# ddf = dd.from_pandas(df, npartitions=4)
# ddf_rolling = ddf['sales'].rolling(window=3).median()
# result = ddf_rolling.compute()

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

12. الأخطاء الشائعة واستراتيجيات استكشاف الأخطاء وإصلاحها

12.1 أخطاء الترتيب والفهارس غير المتسقة

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

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

# فحص سلامة الفهرس وخلوه من التكرار والترتيب الخاطئ
assert df_time.index.is_monotonic_increasing, "خطأ: الفهرس الزمني غير مرتب تصاعدياً!"
assert not df_time.index.has_duplicates, "تحذير: توجد طوابع زمنية مكررة في البيانات!"

12.2 أخطاء تسرب البيانات (Data Leakage) في النمذجة التنبؤية

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

  • الاستخدام الكارثي للنافذة المتمركزة (center=True): يؤدي تفعيل هذا المعامل إلى تضمين قراءات مستقبلية تقع بعد النقطة الزمنية $t$ في حساب وسيط اللحظة $t$. وبالتالي، فإن النموذج التنبؤي سيتدرب على رؤية معلومات من المستقبل، وهو ما ينتهك المبدأ السببي الأساسي للتنبؤ الزمني.
  • تضمين القيمة الراهنة $t$ للتنبؤ بالخطوة $t$: حتى مع استخدام النوافذ الاعتيادية (المحاذاة لليمين)، فإن وسيط النافذة المنتهية عند $t$ يحتوي على رصدة اللحظة $t$ نفسها. إذا كان الهدف هو التنبؤ بقيمة اللحظة $t$ استناداً إلى خصائص تاريخية سابقة، فإن تضمين القيمة الحالية داخل خاصية الوسيط يمثل تسرباً مباشراً للهدف التنبؤي (Target Leakage).

للوقاية الصارمة من تسرب البيانات، يجب دائماً استخدام دالة الإزاحة الزمنية shift(1) لتأخير متجه الوسيط المتدحرج بمقدار خطوة واحدة كاملة إلى الأمام، مما يضمن أن كل خاصية تم إنشاؤها لتدريب النموذج تعتمد حصرياً على الماضي المستقر:

# التطبيق الوقائي الحصين لمنع تسرب البيانات في هندسة الخصائص
df['feature_safe_med_3'] = df['sales'].rolling(window=3).median().shift(1)
print(df[['sales', 'feature_safe_med_3']].head(6))

12.3 أخطاء الأنواع الحسابية وتعديل البيانات في موضعها

تثير عمليات إنشاء وتعيين الأعمدة المتدحرجة تحذيرات ومشاكل برمجية شائعة تتعلق بإدارة الذاكرة وأنواع البيانات داخل إطار بانداز، ويأتي في مقدمتها:

خطأ الأنواع غير المتوافقة (Object Data Types): إذا كان العمود الرقمي المستهدف يحتوي على نصوص مخفية أو مسافات فارغة تجعل نوعه object بدلاً من float أو int، فإن استدعاء rolling().median() سيلقي استثناء برمجياً فورياً يفيد بعدم إمكانية إجراء العمليات الحسابية الرتبية على كائنات عامة. يجب دائماً تنظيف الأعمدة وتحويلها عبر pd.to_numeric(df['col'], errors='coerce') قبل الحساب.

تحذير التعديل على شريحة منسوخة (SettingWithCopyWarning): يظهر هذا التحذير المزعج بكثرة عند تطبيق الحساب المتدحرج على إطار بيانات فرعي تم استخراجه كشريحة عبر تصفية شرطية دون استخدام النسخ الصريح عبر .copy(). لتفادي هذا التحذير البرمجي وضمان التعديل الآمن في الذاكرة، يجب اعتماد الفهرسة الصريحة باستخدام محدد الموقع .loc[]:

# الاستخدام البرمجي الموصى به لتفادي تحذيرات التعيين
df.loc[:, 'sales_rolling_final'] = df['sales'].rolling(window=3).median()

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

عنصر الفحص المنهجي الإجراء البرمجي الموصى به الأهمية التقنية والتحليلية
ترتيب المحور الزمني df.sort_index() أو sort_values() منع دمج رصدات متباعدة داخل نفس النافذة الحسابية
سلامة أنواع الأعمدة pd.to_numeric() تفادي توقف الخوارزميات بسبب أنواع البيانات النصية (Object)
الحماية من تسرب البيانات استخدام .shift(1) وتجنب center=True ضمان النزاهة التنبؤية للنماذج المستقبلية ومنع الرؤية الاستباقية
إدارة أطراف السلسلة تحديد قيمة min_periods الواعية الموازنة الدقيقة بين تفادي قيم NaN وثبات دقة التقدير الإحصائي
تفكيك الفهارس المزدوجة استخدام reset_index() أو transform() تجنب أخطاء عدم تطابق أبعاد المصفوفات مع إطار البيانات الأصلي

خاتمة

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

وقد أوضح هذا الدليل الشامل أن الاستثمار الأمثل لقدرات دالة rolling().median() في بانداز يتجاوز مجرد كتابة تعبير برمجي مبسط؛ إذ يتطلب فهماً عميقاً للتفاعل البنيوي بين معاملات التحكم المتطورة مثل min_periods لإدارة الفقد المبكر، وcenter لضبط التماثل الطوري، وclosed لعزل الأطراف الطرفية، بالإضافة إلى الإتقان الكامل لتقنيات الربط الزمني المستند إلى الفترات الفيزيائية عبر DatetimeIndex والتجميع العازل للكيانات باستخدام groupby().

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

المراجع

تقييم هذا المحتوى

0.0 / 5 0 تقييمات

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

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