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

كيفية إنشاء عمود تأخير في بانداس (مع أمثلة)


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

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

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

1. مقدمة نظرية لمفهوم التأخير الزمني (Lag) وأهميته في تحليل السلاسل الزمنية

1.1 التعريف الأكاديمي لمتغير التأخير الزمني (Lagged Variable)

يُعرَّف متغير التأخير الزمني في الأدبيات الإحصائية والاقتصادية القياسية بأنه قيمة متغير معين تم رصدها في فترة زمنية سابقة للفترة الحالية. إذا افترضنا وجود متسلسلة زمنية نرمز لها بالرمز Y عند اللحظة الزمنية t، فإن القيمة المتأخرة بفترة زمنية واحدة يُرمز لها بالرمز Yt-1، بينما يُرمز للتأخير بمقدار k من الفترات بالرمز Yt-k. تكمن الأهمية النظرية لهذا التحويل في كونه حجر الزاوية لحساب ظاهرة الارتباط الذاتي (Autocorrelation)، وهي الخاصية الإحصائية التي تعبر عن مدى اعتماد القيمة الحالية لمتغير ما على قيمه السابقة، مما يكسر فرضية استقلال المشاهدات الشائعة في الإحصاء التقليدي.

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

1.2 استخدامات أعمدة التأخير في بحوث البيانات والنماذج الاقتصادية والسلوكية

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

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

1.3 مقارنة بين التأخير الإيجابي (Lag) والتقديم المستقبلي (Lead)

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

في المقابل، يُعنى التقديم المستقبلي أو ما يُعرف بـ Lead بجلب قيم مستقبلية Yt+k وربطها باللحظة الحالية t عبر إزاحة البيانات إلى الخلف. يقتصر استخدام هذا النمط على التحليلات البعدية (Ex-post Analysis) ودراسات تقييم الأثر المالي أو الاقتصادي بعد وقوع الأحداث، بالإضافة إلى استخدامه في بناء المتغير التابع أو المستهدف (Target Variable) في مهام التعلم الخاضع للإشراف. يؤثر كل من النمطين بشكل مباشر على استقرار المتسلسلة الزمنية؛ إذ إن الخلط غير المنضبط بينهما يؤدي حتماً إلى تدمير البنية الزمنية السببية وتوليد نتائج مضللة غير قابلة للتطبيق العملي.

2. الأساس البرمجي لدالة shift() في مكتبة Pandas

2.1 التشريح الدقيق للصيغة البرمجية والمعاملات (Parameters)

تُعد دالة shift() الأداة الأساسية والمعيارية داخل مكتبة Pandas لتنفيذ عمليات الإزاحة الزمنية على كل من كائنات السلاسل (Series) وإطارات البيانات (DataFrame). تتميز هذه الدالة بمرونتها العالية وتصميمها الموجه لدعم العمليات المصفوفية السريعة. تأخذ الدالة توقيعاً برمجياً دقيقاً يتضمن مجموعة من المعاملات المحورية التي تتحكم في سلوك الإزاحة واتجاهها:

  • periods: يمثل هذا المعامل عدداً صحيحاً يحدد حجم واتجاه الإزاحة الإحصائية. القيمة الافتراضية هي 1، والتي تعبر عن تأخير زمني بمقدار خطوة واحدة (Lag 1). في حال تمرير قيمة سالبة، تتحول العملية إلى تقديم مستقبلي (Lead).
  • freq: يُستخدم هذا المعامل الاختياري للتعامل مع الفهارس الزمنية المتخصصة من نوع DatetimeIndex أو PeriodIndex. عند تحديد هذا المعامل، تقوم الدالة بإزاحة الفهرس الزمني نفسه بمقدار التردد المحدد بدلاً من تحريك مصفوفة القيم، مما يحافظ على ترابط البيانات دون توليد قيم مفقودة في مصفوفة القيم.
  • axis: يحدد محور المعالجة؛ حيث تشير القيمة 0 (أو ‘index’) إلى تطبيق الإزاحة رأسياً عبر الصفوف، وهو الاستخدام الأكثر شيوعاً في تحليل السلاسل الزمنية، بينما تشير القيمة 1 (أو ‘columns’) إلى تطبيق الإزاحة أفقياً عبر الأعمدة.
  • fill_value: يتيح هذا المعامل تحديد قيمة بديلة لتعويض البيانات المفقودة (NaN) التي تنشأ تلقائياً عند حواف البيانات نتيجة عملية الإزاحة، مما يمنع التحويل غير المرغوب فيه للأنواع العددية الصحيحة إلى أعداد عشرية.

2.2 آلية عمل محرك الفهرسة عند تنفيذ الإزاحة

يعتمد المحرك الداخلي لمكتبة Pandas عند استدعاء shift() على إدارة ذكية لمصفوفات NumPy الأساسية المرتبطة بالفهرس (Index). عند تنفيذ إزاحة موجبة بمقدار k على مستوى الصفوف (axis=0)، يقوم المحرك بنقل عناصر مصفوفة البيانات بمقدار k خانة نحو المؤشرات الأعلى، مع الحفاظ الصارم على ثبات بنية الفهرس الأصلي دون أي تعديل في تسمياته أو ترتيبه. يترتب على ذلك خروج العناصر الأخيرة التي تتجاوز الحد الأعلى للمصفوفة، وتفريغ المواقع الأولى المقابلة للمؤشرات من 0 إلى k-1.

تتم معالجة هذه المواقع المفرغة منطقياً بإسناد القيمة غير المعرفة القياسية np.nan أو القيمة المحددة في fill_value. يتعامل المحرك بكفاءة مع مختلف أنواع البيانات؛ ففي السلاسل النصية (Object/String) تُملأ الفجوات بالرمز None أو NaN، بينما في السلاسل الزمنية (Datetime64) تُملأ بـ NaT (Not a Time)، مما يضمن التناسق الداخلي للأطر الهيكلية مع الحفاظ على الكفاءة الذاكرية للعمليات الموجهة.

2.3 التدقيق في مخرجات الدالة والتحقق من التناسق الهيكلي

عند تطبيق دالة shift()، يُظهر الفحص الهيكلي ثباتاً مطلقاً في أبعاد إطار البيانات الأصلي؛ حيث يظل عدد الصفوف والأعمدة متطابقاً تماماً مع الحالة الابتدائية قبل الإزاحة. ومع ذلك، يجب على محلل البيانات الانتباه إلى الآثار الجانبية المرتبطة بالتحويل الضمني للأنواع (Implicit Type Casting). فعلى سبيل المثال، إذا كان العمود الأصلي يحتوي على أعداد صحيحة (integers)، فإن إدخال القيمة NaN في الصفوف الأولى سيجبر Pandas تلقائياً على ترقية نوع البيانات إلى أعداد عشرية (float64)، نظراً لأن المعيار الكلاسيكي لـ NaN في لغة بايثون يتبع تمثيل النقطة العائمة IEEE 754.

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

3. تطبيق عملي خطوة بخطوة: إنشاء عمود تأخير بسيط (Lag 1)

3.1 بناء بيئة العمل وتجهيز إطار البيانات التجريبي

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

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

3.2 تنفيذ الإزاحة الفردية وربط العمود الجديد بالإطار

لتوليد عمود التأخير البسيط من الدرجة الأولى (Lag 1)، نقوم بتطبيق الصيغة البرمجية المباشرة التي تستهدف عمود المبيعات وتزيحه بمقدار فترة واحدة، ومن ثم إسناد المخرجات إلى عمود جديد داخل إطار البيانات، كالتالي:

يتم استدعاء df['sales_lag1'] = df['sales'].shift(1). عند فحص الجدول الناتج، نلاحظ بوضوح أن القيمة المسجلة للمبيعات في اليوم الأول قد انتقلت لتصبح في صف اليوم الثاني ضمن العمود الجديد، بينما أصبحت القيمة المقابلة لليوم الأول في عمود التأخير هي NaN. يعكس هذا التطابق الدقيق نقل المعلومات التاريخية بمقدار وحدة زمنية واحدة إلى الأمام، مما يتيح مقارنة مبيعات كل يوم بمبيعات اليوم الذي سبقه مباشرة داخل نفس الصف التحليلي.

3.3 تحليل الأثر الرياضي للإزاحة الفردية على المتسلسلة

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

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

4. توليد فترات تأخير متعددة (Multiple Lags) وهندسة الميزات المتقدمة

4.1 إنشاء حزم تأخير زمنية متتابعة (Lag 1 through Lag N)

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

يتم تعريف نطاق التأخيرات المطلوبة، وليكن من 1 إلى 5، ثم نقوم بتوليد الأعمدة الجديدة بأسماء ديناميكية موثقة مثل sales_lag_1 و sales_lag_2. إن إسناد هذه الميزات دفعة واحدة يسهم في الحفاظ على استقرار بنية الذاكرة التخزينية المخصصة لأعمدة Pandas ويوفر أساساً متيناً لبناء مصفوفة المدخلات لنماذج الانحدار الخطي المتعدد.

4.2 توليد تأخيرات ذات فترات متباعدة (Seasonal / Weekly Lags)

تتميز بعض الظواهر بوجود دورات زمنية موسمية أو أسبوعية منتظمة تفرض استخدام تأخيرات متباعدة غير متصلة. في البيانات اليومية، يمثل التأخير بمقدار 7 فترات (Lag 7) ميزة استراتيجية بالغة الأهمية لرصد النمط الأسبوعي؛ حيث تتم مقارنة مبيعات يوم الجمعة الحالي بمبيعات يوم الجمعة من الأسبوع المنصرم مباشرة.

وبالمثل، يُستخدم التأخير بمقدار 30 فترة (Lag 30) للأنماط الشهرية، و365 فترة (Lag 365) للأنماط السنوية في سلاسل البيانات اليومية. تجدر الإشارة إلى أنه كلما زادت قيمة فترة الإزاحة k، ازداد عدد القيم المفقودة المتراكمة في بداية السلسلة، وهو ما يجب أخذه في الحسبان عند تقييم حجم العينة الفعال المتبقي للتدريب والنمذجة الرياضية.

4.3 دمج الأعمدة المتأخرة في إطار مصفوفي موحد

تُعد الطريقة المثلى لإنشاء مصفوفات الميزات المتعددة من الناحية البرمجية هي استخدام دالة pd.concat(). بدلاً من إدراج كل عمود متأخر على حدة داخل حلقة تكرارية، يتم توليد قاموس أو قائمة تحتوي على كافة السلاسل المزاحة دفعة واحدة، ثم دمجها أفقياً مع إطار البيانات الأصلي عبر المحور axis=1.

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

5. التعامل المنهجي مع القيم المفقودة (NaN) الناتجة عن التأخير

5.1 الأسباب الهيكلية لظهور القيم المفقودة عند حواف البيانات

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

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

5.2 استراتيجيات الاستبعاد والمعالجة (Drop vs. Imputation)

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

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

5.3 استخدام وسيط fill_value داخل دالة shift() مباشرة

توفر مكتبة Pandas حلاً برمجياً متكاملاً لمعالجة القيم المفقودة لحظة إنشائها عبر المعامل fill_value في دالة shift(). يتيح هذا المعامل تحديد قيمة بديلة ثابتة تحل محل NaN دون الحاجة إلى استدعاء دوال معالجة إضافية لاحقة.

في التطبيقات الاقتصادية وسلاسل التوريد، يُعد استخدام fill_value=0 خياراً شائعاً ومنطقياً عند دراسة مبيعات المنتجات الجديدة؛ حيث يعبر الصفر بدقة عن انعدام النشاط التجاري قبل تاريخ إطلاق المنتج. كما يمكن استخدام القيمة الأولى كمعوض ثابت (Static Boundary Imputation) في حالات خاصة، مع ضرورة توثيق هذا الإجراء لضمان الشفافية وقابلية التدقيق العلمي للنموذج الرياضي.

6. الإزاحة العكسية (Negative Lags / Lead) والتحليل المستقبلي

6.1 الصيغة الرياضية والبرمجية للإزاحة السالبة

تُنفذ الإزاحة العكسية أو التقديم المستقبلي (Lead) في Pandas عن طريق تمرير قيمة سالبة للمعامل periods في دالة shift()، مثل df['sales_lead1'] = df['sales'].shift(-1). من الناحية الرياضية، تقوم هذه العملية بإقران المشاهدة الحالية في اللحظة t بالقيمة المستقبلية التي ستحدث في اللحظة t+1.

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

6.2 حالات الاستخدام الأكاديمي والتحليلي للمتغيرات المستقبلية

تكتسب المتغيرات المستقبلية المشتقة بواسطة shift(-k) أهمية بالغة في الأبحاث الأكاديمية والمالية. تُستخدم هذه الميزات في حساب عوائد الأصول المالية المستقبلية (Forward Looking Returns)، حيث يُقاس العائد المتوقع لورقة مالية عبر مقارنة سعر إغلاق اليوم بسعر إغلاق الغد.

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

6.3 محاذير استخدام Lead لتجنب تسرب البيانات (Lookahead Bias)

يُمثل استخدام ميزات التقديم المستقبلي (Lead) أحد أخطر مصادر الخطأ المنهجي في علم البيانات إذا لم يُضبط بحذر شديد؛ حيث يؤدي إدراج أي متغير مستقبلي كميزة تفسيرية (Predictor) داخل مصفوفة التدريب إلى ما يُعرف بـ تحيز التطلع المستقبلي (Lookahead Bias) أو تسرب البيانات (Data Leakage).

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

7. حساب الفروقات الزمنية ومعدلات النمو عبر دمج Lags

7.1 حساب الفروق البسيطة والفروق النسبية يدوياً

يُعد الجمع بين العمود الأصلي وعمود التأخير الزمني الوسيلة الرياضية المباشرة لحساب التغير المطلق والتغير النسبي عبر الزمن. يتم صياغة معادلة الفرق المطلق يدوياً عبر طرح القيمة المتأخرة من القيمة اللحظية:

df['diff_manual'] = df['sales'] - df['sales'].shift(1)

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

df['pct_manual'] = (df['sales'] - df['sales'].shift(1)) / df['sales'].shift(1)

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

7.2 حساب معدلات التسارع والتغير من الدرجة الثانية

تمثل الفروق من الدرجة الثانية (Second-order Differences) المشتقة الثانية المنفصلة للسلسلة الزمنية، وتُستخدم لقياس معدل تسارع النمو أو التباطؤ بدلاً من مجرد قياس التغير الخطي. يتم توليد هذه الفروق عبر تطبيق إزاحة متتالية أو بطرح فروق الدرجة الأولى المتأخرة من فروق الدرجة الأولى الحالية:

df['acceleration'] = df['sales'].diff() - df['sales'].diff().shift(1)

تكتسب هذه الفروق المركبة أهمية كبرى في تحويل السلاسل الزمنية غير المستقرة التي تحتوي على اتجاه عام تربيعي (Quadratic Trend) إلى سلاسل مستقرة (Stationary Series)؛ وهو شرط أساسي لتطبيق نماذج بوكس-جينكينز (ARIMA)، مما يضمن عدم تضليل الاختبارات الإحصائية بفعل الانحدارات الزائفة.

7.3 تطبيق دالة pct_change() ومقارنتها الهيكلية مع shift()

توفر مكتبة Pandas دالة مدمجة عالية الأداء تُعرف بـ pct_change()، والتي تقوم داخلياً بتنفيذ الإزاحة وحساب النسبة المئوية للتغير في خطوة واحدة محسنة حسابياً. ترتبط هذه الدالة بنيوياً بـ shift()، حيث تكافئ تماماً العملية الرياضية (x - x.shift(periods)) / x.shift(periods).

ومع ذلك، يُفضل الاعتماد المباشر على shift() في الحالات التي تتطلب عمليات حسابية مخصصة أو دمجاً معقدة، مثل حساب العوائد اللوغاريتمية np.log(df['sales'] / df['sales'].shift(1))، أو عند الحاجة لمعالجة حالات القسمة على الصفر وتجنب توليد قيم اللانهاية (Infinity) التي قد تفسد مراحل التدريب اللاحقة.

8. تطبيق التأخير الزمني ضمن المجموعات والتصنيفات (Groupby with Shift)

8.1 تحديات تطبيق الإزاحة على البيانات المقطعية المجمعة (Panel Data)

تواجه معالجة البيانات المقطعية الزمنية المجمعة (Panel Data أو Longitudinal Data)—التي تحتوي على سلاسل زمنية متوازية لعدة كيانات مثل مبيعات عدة متاجر أو مؤشرات عدة شركات—تحدياً منهجياً خطيراً عند تطبيق الإزاحة المباشرة. إذا تم استدعاء shift() مباشرة على العمود بالكامل دون عزل الكيانات، فستحدث كارثة تحليلية تتمثل في انتقال القيمة الأخيرة للمتجر الأول لتصبح هي القيمة المتأخرة للصف الأول الخاص بالمتجر الثاني.

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

8.2 الصيغة البرمجية لدمج groupby() مع دالة shift()

لضمان العزل الحسابي التام وحماية حدود الكيانات المستقلة، توفر Pandas تكاملاً قوياً بين دالة التجميع groupby() ودالة الإزاحة shift(). تُصاغ العملية برمجياً بالشكل التالي:

df['lagged_sales'] = df.groupby('store_id')['sales'].shift(1)

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

8.3 التعامل مع التجميعات المتعددة والمركبة

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

df['lag_multi'] = df.groupby(['country', 'city', 'store_id', 'department'])['sales'].shift(1)

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

9. معالجة السلاسل الزمنية غير المنتظمة ومحاذاة التواريخ

9.1 أثر التواريخ المفقودة على دقة التأخير المستند إلى الصفوف

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

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

9.2 استخدام معامل freq مع الفهارس الزمنية (DatetimeIndex)

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

عند تنفيذ df.shift(freq='1D')، لا تقوم Pandas بتحريك مصفوفة القيم إطلاقاً، بل تقوم بزيادة قيم الفهرس الزمني بمقدار يوم تقويمي واحد لكل صف. يضمن هذا النهج محاذاة البيانات وفقاً للتاريخ الفعلي بدقة متناهية، والتعامل السليم مع المناطق الزمنية المختلفة والتوقيت الصيفي دون الإخلال بالمحتوى الرقمي للبيانات.

9.3 إعادة العينات والمحاذاة المسبقة (Resampling & Reindexing)

تتمثل الاستراتيجية الأكثر شمولاً وتماسكاً في إعادة تشكيل بنية السلسلة الزمنية لتصبح منتظمة بالكامل قبل الشروع في توليد أعمدة التأخير. يتم ذلك عبر استخدام دالة إعادة أخذ العينات resample() أو دالة إعادة الفهرسة reindex():

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

10. التطبيقات الإحصائية والنماذج التنبؤية المعتمدة على متغيرات التأخير

10.1 نماذج الانحدار الذاتي (Autoregressive Models – AR)

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

Yt = c + φ1Yt-1 + φ2Yt-2 + … + φpYt-p + εt

يمكن بناء هذا النموذج يدوياً وبسهولة فائقة في بايثون عبر توليد p من أعمدة التأخير باستخدام shift()، ثم تغذيتها مباشرة إلى مكتبة statsmodels أو scikit-learn كمتغيرات مفسرة في مصفوفة X. يُستعان بمخططات الارتباط الذاتي (ACF) والارتباط الذاتي الجزئي (PACF) لتحديد الرتبة المثلى p وتفادي الإفراط في تعقيد النموذج دون مبرر إحصائي.

10.2 المتوسطات المتحركة المشتقة من فترات التأخير (Lagged Rolling Windows)

تُمثل النوافذ المتحركة المتأخرة (Lagged Rolling Features) أداة متقدمة وهامة للغاية في هندسة الميزات الزمنية. إذا تم تطبيق دالة المتوسط المتحرك rolling(window=7).mean() مباشرة على السلسلة، فإن المتوسط المحسوب عند اللحظة t سيتضمن بالضرورة القيمة الحالية Yt، مما يجعله غير صالح للاستخدام كميزة تنبؤية للتنبؤ بـ Yt نفسها.

لحل هذه المعضلة وتفادي تسرب البيانات، يتم دمج shift() مع rolling() وفق الصيغة المنهجية التالية:

df['lagged_rolling_mean_7'] = df['sales'].shift(1).rolling(window=7).mean()

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

10.3 تغذية خوارزميات التعلم الآلي (XGBoost, Random Forest) بالمتغيرات المتأخرة

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

عند تدريب هذه النماذج، يجب تطبيق بروتوكول تقسيم البيانات الزمني (Time-based Split) بدلاً من التقسيم العشوائي التقليدي؛ لضمان تدريب النموذج على الماضي واختباره على المستقبل. تتيح مصفوفات التأخير للباحث استخراج درجات أهمية الميزات (Feature Importance)، مما يكشف عن الفترات الزمنية الأكثر تأثيراً في صياغة السلوك المستقبلي للمتغير المستهدف.

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

11.1 استهلاك الذاكرة عند تكرار إنشاء أعمدة التأخير

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

للحد من هذا الاستهلاك، يُنصح بإجراء تخفيض استباقي لأنواع البيانات (Downcasting)، مثل تحويل الأعداد العشرية من float64 إلى float32، والأعداد الصحيحة من int64 إلى int32 أو int16 قبل تطبيق الإزاحة. كما يجب حذف المتغيرات الوسيطة غير الضرورية واستدعاء جامع القمامة في بايثون gc.collect() لتحرير مساحات الذاكرة غير المستغلة باستمرار.

11.2 المعالجة السريعة باستخدام مصفوفات NumPy

في بيئات الإنتاج فائقة السرعة التي تتطلب معالجة فورية وتأخيراً زمنياً منخفضاً (Low Latency)، يمكن تجاوز الطبقات الإدارية الإضافية في Pandas والتوجه مباشرة نحو مصفوفات NumPy الأساسية. توفر مكتبة NumPy دوال إزاحة سريعة للغاية مثل np.roll()، مع ضرورة الانتباه إلى أن np.roll() تقوم بتدوير العناصر وإعادة الصفوف الأخيرة إلى البداية بدلاً من وضع NaN.

لتطبيق إزاحة صحيحة إحصائياً عبر NumPy بسرعة قصوى، يتم إنشاء مصفوفة فارغة مملوءة بالقيم غير المعرفة وتخصيص القيم المزاحة إليها عبر التقطيع المباشر للمصفوفات (Array Slicing):

يتميز هذا النهج الشعاعي البحت بتفوقه الكاسح في السرعة الحسابية مقارنة بـ Pandas، مما يجعله الخيار المفضل في خوارزميات التداول المالي عالي التردد (HFT) ومعالجة تدفقات البيانات اللحظية.

11.3 استخدام مكتبات المعالجة المتوازية (Polars, Dask) للبيانات المليونية

عندما يتجاوز حجم البيانات سعة الذاكرة العشوائية للجهاز (Out-of-Core Processing)، تبرز مكتبات الحوسبة المتقدمة كبدائل متطورة لمكتبة Pandas:

  • مكتبة Polars: مكتوبة بلغة Rust وتعتمد على محرك حوسبة متعدد الخيوط ومعمارية Apache Arrow. توفر دالة shift() فائقة السرعة مع دعم كامل لتقنية التقييم الكسول (Lazy Execution)، حيث يتم تحسين مخطط الاستعلام بالكامل قبل التنفيذ الفعلي لتقليل العمليات غير الضرورية.
  • مكتبة Dask: تتيح توزيع إطارات البيانات الكبيرة عبر كتل متعددة ومعالجتها بالتوازي على مستوى المعالجات المتعددة أو المجموعات السحابية الموزعة (Clusters)، مما يتيح تطبيق الإزاحة على مجموعات بيانات بمليارات الصفوف بكفاءة تامة.

12. الأخطاء الشائعة والبروتوكولات الأكاديمية لضمان سلامة التحليل

12.1 خطأ إهمال الترتيب الزمني قبل تطبيق الإزاحة (Sorting Issues)

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

إذا كانت البيانات مرتبة عشوائياً أو مفروزة وفق عمود آخر مثل حجم المبيعات أو المعرف الأبجدي، فإن عمود التأخير الناتج سيحتوي على قيم لا علاقة لها بالماضي الحقيقي للمشاهدة. لذلك، يُعد تطبيق بروتوكول الفرز الإلزامي df = df.sort_values('date').reset_index(drop=True) خطوة تمهيدية مقدسة لا تقبل الإهمال قبل الشروع في أي عملية إزاحة زمنية.

12.2 تسرب البيانات أثناء خطوة ما قبل المعالجة (Data Preprocessing Leakage)

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

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

12.3 قائمة الفحص النهائية (Checklist) لاعتماد ميزات التأخير الزمني

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

  • التحقق الصارم من الترتيب الزمني التصاعدي للبيانات وخلو الفهرس من الفجوات غير المعالجة.
  • التأكد من عزل المجموعات والكيانات المنفصلة عبر groupby() لمنع تسرب البيانات بين الوحدات المقطعية.
  • التأكد من عدم استخدام أي إزاحة سالبة (Lead) داخل مصفوفة الميزات المستقلة X لتفادي تحيز التطلع المستقبلي.
  • المعالجة الدقيقة والواعية للقيم المفقودة (NaN) في بداية السلسلة وتوثيق الاستراتيجية المتبعة رياضياً.
  • فحص استقرار السلسلة الزمنية بعد إدراج الفروقات والتأخيرات وتوثيق المبرر الإحصائي لاختيار فترات التأخير استناداً إلى دالتي ACF و PACF.

خاتمة

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

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

References

  • Box, G. E., Jenkins, G. M., Reinsel, G. C., & Ljung, G. M. (2015). Time series analysis: Forecasting and control (5th ed.). John Wiley & Sons. https://doi.org/10.1002/9781118619193
  • Hamilton, J. D. (1994). Time series analysis. Princeton University Press. https://doi.org/10.2307/j.ctv1416454
  • Hyndman, R. J., & Athanasopoulos, G. (2021). Forecasting: Principles and practice (3rd ed.). OTexts. https://otexts.com/fpp3/
  • 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. (2024). pandas-dev/pandas: Pandas documentation (v2.2.0). Zenodo. https://pandas.pydata.org/docs/
  • Wooldridge, J. M. (2020). Introductory econometrics: A modern approach (7th ed.). Cengage Learning.

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

looti, M. (2026, سبتمبر 2). كيفية إنشاء عمود تأخير في بانداس (مع أمثلة). عرب سايكلوجي. https://arabpsychology.com/how-to-create-lag-column-pandas-examples/
looti, Mohammed. “كيفية إنشاء عمود تأخير في بانداس (مع أمثلة).” عرب سايكلوجي, 2 سبتمبر 2026, https://arabpsychology.com/how-to-create-lag-column-pandas-examples/.
looti, Mohammed. “كيفية إنشاء عمود تأخير في بانداس (مع أمثلة).” عرب سايكلوجي. سبتمبر 2, 2026. https://arabpsychology.com/how-to-create-lag-column-pandas-examples/.