كيفية الاحتفاظ بأعمدة معينة في PySpark (مع أمثلة)

دليل أكاديمي شامل يشرح كيفية الاحتفاظ بأعمدة معينة في PySpark DataFrames باستخدام دوال select وdrop مع أمثلة برمجية وتحليل للأداء الحاسوبي.

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

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

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

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

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

1. مقدمة شاملة لإدارة وتصفية الأعمدة في إطار عمل PySpark

1.1 أهمية تحديد الأعمدة في معالجة البيانات الضخمة

تمثل الذاكرة العشوائية الموزعة (Distributed RAM) المورد الأكثر حساسية وتكلفة في العناقيد الحوسبية (Compute Clusters) المخصصة لمعالجة البيانات الضخمة. عند تحميل مجموعات البيانات العريضة التي تحتوي على مئات المتغيرات، يؤدي الاحتفاظ بالأعمدة الزائدة التي لا تدخل في العمليات التحليلية اللاحقة إلى استهلاك غير مبرر لمساحات التخزين المؤقت في الذاكرة. ينتج عن هذا التراكم زيادة الضغط على آليات جمع القمامة (Garbage Collection) في الآلة الافتراضية للجافا (JVM)، وقد يتصاعد الأمر ليقود إلى انهيار وحدات التنفيذ بسبب أخطاء نفاد الذاكرة الشهيرة (java.lang.OutOfMemoryError).

بالإضافة إلى قيود الذاكرة، فإن نقل البيانات بين العقد الحوسبية عبر الشبكة الفيزيائية (Network I/O) يشكل في كثير من الأحيان عنق الزجاجة الرئيسي (Bottleneck) للأداء العام. عندما تتضمن العمليات التحويلية مراحل إعادة توزيع للبيانات (Shuffle Operations)، كالفرز أو التجميع أو الربط، فإن كل عمود إضافي يتم تضمينه يضاعف من حجم حزم البيانات المشفرة والمنقولة عبر كابلات الشبكة. تقليص عدد الأعمدة في المراحل المبكرة من خط المعالجة يضمن خفضاً جذرياً في أزمنة الإرسال والاستقبال وتقليل تشتت النطاق الترددي للشبكة المشتركة.

علاوة على ذلك، يرتبط زمن المعالجة ارتباطاً وثيقاً بكمية البيانات المقروءة من وسائط التخزين الدائمة، مثل منظومة الملفات الموزعة Hadoop Distributed File System أو منصات التخزين السحابي مثل Amazon S3 و Google Cloud Storage. التحديد المبكر للأعمدة يتيح للمحرك تفعيل تقنيات قراءة المقاطع المطلوبة فقط، مما يقلص بصمة الإدخال والإخراج ويسرع التحويلات اللاحقة بمستويات قد تصل إلى أضعاف السرعة الأصلية.

1.2 الفلسفة المعمارية لهياكل البيانات DataFrames في Apache Spark

تستند هياكل البيانات المجدولة في PySpark إلى مفهوم عدم القابلية للتغيير (Immutability)، وهي خاصية متأصلة ورثتها عن مجموعات البيانات الموزعة المرنة (Resilient Distributed Datasets – RDDs) التي أسس لنظريتها زاهاريا وزملاؤه (Zaharia et al., 2012). يعني هذا المبدأ أن أي عملية تصفية أو انتقاء للأعمدة لا تُعدل إطار البيانات الحالي إطلاقاً، بل تُنشئ كائناً برمجياً جديداً يمثل حالة البيانات بعد التحويل، مما يضمن أمان التزامن وخلو المنظومة من الآثار الجانبية أثناء التنفيذ الموازي على آلاف الأنوية الحوسبية.

ترتبط هذه الطبيعة ارتباطاً وثيقاً بآلية التقييم الكسول (Lazy Evaluation). في PySpark، تنقسم العمليات البرمجية إلى تحويلات (Transformations) مثل اختيار الأعمدة وتصفية الصفوف، وإجراءات تنفيذية (Actions) مثل حساب عدد السجلات أو استعراض العينات. عندما يقوم المهندس بتحديد أعمدة معينة، لا يقوم Spark بتنفيذ العملية لحظياً، بل يكتفي بتسجيلها كعقدة في رسم بياني غير دوري موجه (Directed Acyclic Graph – DAG) يُعبر عن سلالة البيانات وتاريخ التحويلات.

يتولى محرك التحسين العلائقي، المعروف باسم Catalyst Optimizer والذي وضعت معالمه الأساسية دراسة أرمبروست وفريقه (Armbrust et al., 2015)، فحص هذا الرسم البياني وتحويله من مخطط منطقي غير محسن إلى مخطط فيزيائي فائق الكفاءة. يقوم المحرك بإعادة ترتيب العمليات، ودمج خطوات الإسقاط المتتابعة، والتخلص من الاستعلامات الفرعية غير الضرورية قبل البدء الفعلي بتوليد الأكواد البرمجية للآلة عبر محرك Tungsten، مما يمنح المطور كفاءة أداء مستقلة نسبياً عن أسلوب الصياغة الظاهري.

1.3 المقارنة المنهجية بين استراتيجيات الإبقاء والحذف

تنقسم الممارسات الهندسية لاختيار الأعمدة إلى فلسفتين أساسيتين: منهجية الاختيار الإيجابي (Whitelisting / Inclusion) ومنهجية الاستبعاد السلبي (Blacklisting / Exclusion). تعتمد المنهجية الأولى على التصريح المباشر بالأعمدة المطلوبة حصراً، بينما تعتمد المنهجية الثانية على تحديد الأعمدة غير المرغوبة وإسقاطها من الهيكل المتاح. يعتمد الترجيح بين هاتين الاستراتيجيتين على الأهداف الوظيفية وطبيعة تطور مخطط البيانات (Schema Evolution).

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

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

2. تهيئة بيئة العمل وإنشاء DataFrame تجريبي للدراسة

2.1 إعداد جلسة SparkSession وتكوين المعلمات الأساسية

تمثل جلسة SparkSession، التي أُدخلت في إصدار Apache Spark 2.0، نقطة الدخول الموحدة للتعامل مع كافة وظائف الحوسبة الموزعة وواجهات برمجة التطبيقات المنطقية SQL والبيانات المجدولة. لبدء العمل البرمجي، يتعين استيراد هذه الفئة وبناء الكائن باستخدام نمط التصميم الباني (Builder Pattern)، مما يسمح بضبط المعلمات التكوينية بدقة قبل إطلاق العمليات.

يتطلب الإعداد المحلي تحديد معلمات التشغيل الأساسية، وفي مقدمتها اسم التطبيق عبر المعامل appName، ونمط النشر عبر المعامل master الذي يُضبط عادة على القيمة local[*] في بيئات التطوير والاختبار للاستفادة من كافة الأنوية المنطقية المتاحة على المعالج المحلي. كما يتم استيراد الدوال الضرورية مثل دوال الحقول من الحزمة pyspark.sql.functions وأنواع البيانات الأساسية من الحزمة pyspark.sql.types لتوفير بيئة عمل متكاملة تقنياً.

فيما يلي الشيفرة البرمجية المعتمدة لتهيئة بيئة العمل واختبار الاتصال بالمحرك:

from pyspark.sql import SparkSession
from pyspark.sql.functions import col
spark = SparkSession.builder.appName("KeepColumnsTutorial").master("local[*]").getOrCreate()

يضمن استخدام التابع getOrCreate() إعادة استخدام الجلسة الحالية إن وجدت في الذاكرة بدلاً من استنزاف موارد العقدة في محاولات متكررة لبناء سياقات تنفيذ جديدة، وهو ما يتوافق مع أفضل الممارسات المتبعة في منصات التحليل التفاعلي مثل نوادي جوبيتر (Jupyter Notebooks) وبيئات Databricks.

2.2 بناء مجموعة البيانات النموذجية الخاصة بفرق كرة السلة

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

يتم تعريف البيانات الأولية في صورة قائمة من الصفوف أو المصفوفات الفرعية، حيث يشتمل كل عنصر على اسم الفريق (team)، والمؤتمر الجغرافي الذي ينافس فيه (conference)، ومجموع النقاط المسجلة (points)، ومعدل التمريرات الحاسمة (assists)، ومعدل المتابعات الدفاعية والهجومية (rebounds). تتيح هذه التشكيلة فحص تعامل Spark مع أنواع بيانات متباينة تشمل النصوص والأعداد الصحيحة.

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

data = [
    ('Boston Celtics', 'East', 118, 26, 47),
    ('Milwaukee Bucks', 'East', 115, 24, 44),
    ('Denver Nuggets', 'West', 114, 29, 45),
    ('LA Lakers', 'West', 117, 28, 43),
    ('Golden State', 'West', 116, 30, 42)
]
columns = ['team', 'conference', 'points', 'assists', 'rebounds']
df = spark.createDataFrame(data, columns)

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

2.3 فحص المخطط الهيكلي وعرض البيانات الأولية

قبل الشروع في كتابة أي استعلامات لتصفية الحقول، يقتضي البروتوكول الهندسي فحص المخطط الهيكلي الأساسي والتحقق من سلامة البيانات الأولية ومطابقتها للمواصفات المتوقعة. يتم هذا الفحص عبر أداتين رئيسيتين في واجهة PySpark: دالة printSchema() ودالة show().

تُظهر دالة printSchema() الشجرة التركيبية للبيانات؛ موضحة اسم كل عمود، ونوعه الفيزيائي، وخاصية قبول القيم الفارغة (nullable). في مجموعتنا النموذجية، يُظهر المخطط أن عمودي team وconference يتبعان النوع النصي StringType، في حين تتبع أعمدة points وassists وrebounds النوع العددي الصحيح طويل المدى LongType أو IntegerType استناداً إلى المنصة المعالجة.

أما التابع df.show(truncate=False) فيقوم بتحفيز تنفيذ كسول محدود لقراءة السجلات وعرضها في جدول منسق بصرياً. يمثل هذا السجل الأساسي نقطة الانطلاق التي سنقيس عليها نجاح كل تقنية لاحقة، حيث نتأكد من احتواء الجدول الأصلي على خمسة حقول رئيسية تمهيداً لعزل مجموعات جزئية محددة منها في الأقسام القادمة.

3. الأسلوب الأول: الاحتفاظ بالأعمدة عبر التحديد المباشر بالأسماء النصية

3.1 الآلية البرمجية لاستخدام دالة select مع السلاسل النصية

تُمثل دالة select الأداة الأساسية والأكثر شيوعاً في بيئة PySpark لتطبيق عملية الإسقاط الجبري (Projection) المستوحاة من الجبر العلائقي ومحركات قواعد البيانات التقليدية. تتيح هذه الدالة للمهندس استدعاء أسماء الأعمدة المستهدفة مباشرة في صورة معاملات نصية مفصولة بفواصل (String Arguments)، مما يولد إطار بيانات جديداً لا يحتوي إلا على تلك الأعمدة المحددة.

تتميز هذه الآلية بالبساطة القصوى والقراءة البديهية؛ إذ تحاكي جملة الاستعلام القياسية SELECT column1, column2 FROM table في لغة SQL. عندما يمرر المطور أسماء الأعمدة نصياً، يقوم المحلل اللغوي الداخلي لـ Spark بالتحقق من مطابقة النصوص الواردة للأسماء المخزنة في المخطط الهيكلي المرجعي أثناء مرحلة التحليل الأولي للمخطط المنطقي.

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

3.2 تطبيق عملي: استخراج عمودي الفريق والنقاط

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

تتم كتابة الشيفرة البرمجية المنفذة لهذا الاستعلام على النحو التالي:

df_selected = df.select("team", "points")
df_selected.show()

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

3.3 المزايا والقيود الهندسية للتمرير النصي المباشر

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

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

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

4. الأسلوب الثاني: الاحتفاظ بالأعمدة باستخدام كائنات الأعمدة ودالة col

4.1 استيراد واستخدام كائن col من مكتبة pyspark.sql.functions

يمثل التعامل مع الأعمدة بوصفها كائنات برمجية مستقلة (Column Objects) بدلاً من سلاسل نصية مجردة الركيزة الأكثر نضجاً وقوة في واجهة PySpark DataFrame API. لتحقيق ذلك، يوفر الإطار دالة col، المستوردة من مكتبة pyspark.sql.functions، والتي تعمل كمحول وظيفي يأخذ اسم الحقل النصي ويُعيد كائناً من الفئة pyspark.sql.Column يمتلك سلوكيات وخصائص حسابية متقدمة.

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

بالإضافة إلى دالة col، يدعم PySpark استدعاء الأعمدة عبر التعبير المباشر من خلال كائن إطار البيانات نفسه باستخدام صيغة المعامل النقطي df.team أو صيغة الفهرسة المكتفية بالأقواس df['team']، وكلاهما يُعيد كائن Column مطابق وظيفياً لما تنتجه دالة col، وإن كانت الأخيرة تظل الأوسع انتشاراً والأكثر مرونة عند كتابة الدوال المجردة.

4.2 تطبيق عملي: بناء استعلام الإبقاء المعتمد على col

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

تتم كتابة الشفرة التطبيقية على النحو التالي:

from pyspark.sql.functions import col
df_col_selected = df.select(col("team"), col("points"))
df_col_selected.show()

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

4.3 تطبيق عمليات إضافية أثناء عملية الاحتفاظ بالأعمدة

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

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

df_transformed = df.select(
    col("team"),
    col("points").alias("total_points"),
    (col("points") * 1.10).alias("projected_points")
)
df_transformed.show()

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

5. الأسلوب الثالث: التحديد الديناميكي للأعمدة باستخدام القوائم البرمجية

5.1 تمرير مصفوفات الأعمدة مباشرة إلى دالة التحديد

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

يدعم PySpark طريقتين أنيقتين لتمرير قوائم الأعمدة إلى الدالة select. الطريقة الأولى تتمثل في تمرير القائمة كمعامل مفرد مباشر إذا كانت الدالة تدعم ذلك في الإصدارات الحديثة، أو استخدام مشغل تفكيك المعاملات في بايثون، المعروف بمشغل النجمة (Unpacking Operator *)، وهو الأسلوب القياسي الأكثر رسوخاً وتوافقاً عبر مختلف أجيال Spark.

يتم تطبيق هذا الأسلوب البرمجي وفق الصيغة التالية:

target_columns = ["team", "conference", "points"]
df_dynamic = df.select(*target_columns)
df_dynamic.show()

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

5.2 توليد قوائم الأعمدة برمجياً عبر List Comprehension

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

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

stat_cols = [c for c in df.columns if c in ['points', 'assists', 'rebounds']]
df_stats = df.select(*stat_cols)
df_stats.show()

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

5.3 تطبيقات الأتمتة في خطوط معالجة البيانات المعقدة

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

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

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

6. الأسلوب الرابع: استراتيجية الاستبعاد عبر إسقاط الأعمدة الزائدة

6.1 الأساس النظري لدالة drop ومتى تمثل الخيار الأمثل

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

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

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

6.2 تطبيق عملي: إسقاط عمودي المؤتمر والتمريرات الحاسمة

لتوضيح التطبيق العملي لآلية الاستبعاد السلبي، نعود إلى مجموعة البيانات النموذجية الخاصة بكرة السلة، ونفترض أننا نريد الوصول إلى إطار بيانات يحتوي حصراً على اسم الفريق، والنقاط، والمتابعات، مع استبعاد عمودي المؤتمر الجغرافي conference والتمريرات الحاسمة assists.

يدعم PySpark تمرير عدة أسماء أعمدة كمعاملات نصية مستقلة داخل استدعاء واحد لدالة drop، كما يظهر في الشيفرة التالية:

df_dropped = df.drop("conference", "assists")
df_dropped.show()

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

6.3 إسقاط الأعمدة باستخدام قوائم برمجية مفككة

تماماً كما هو الحال مع دالة select، تدعم دالة drop تفكيك القوائم البرمجية لتنفيذ عمليات الحذف المتعدد والمؤتمت. يكتسب هذا الأسلوب أهمية بالغة عندما يتم تعريف الحقول المراد إقصاؤها ديناميكياً عبر استعلامات تفتيشية سابقة، كاستبعاد الحقول التي تخلو تماماً من أي قيم مفيدة أو الحقول المكررة نتيجة عمليات الربط العلائقي (Join Operations).

يتم تنفيذ التفكيك البرمجي لقائمة الإسقاط وفق النمط التالي:

columns_to_exclude = ["conference", "assists"]
df_clean = df.drop(*columns_to_exclude)
df_clean.show()

تتميز دالة drop في PySpark بمرونة فائقة وسلوك متسامح للغاية مقارنة بـ select؛ فعند تمرير اسم عمود غير موجود أصلاً في قائمة الإسقاط، يتجاهل المحرك الاسم بهدوء ويتابع التنفيذ دون إطلاق استثناءات برمجية أو إيقاف سير العمل (Silent Ignore)، مما يجعلها آمنة الاستخدام في سياقات التنظيف التكراري، وإن كان هذا التسامح يتطلب في الوقت نفسه حذراً من المطور لئلا يتجاهل أخطاء إملائية في أسماء الحقول المراد التخلص منها فعلياً.

7. الاحتفاظ بالأعمدة استناداً إلى أنواع البيانات والشروط الوصفية

7.1 تصفية واختيار الأعمدة الرقمية حصرياً

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

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

numeric_types = ['int', 'bigint', 'double', 'float', 'long']
numeric_cols = [c for c, t in df.dtypes if t in numeric_types]
df_numeric = df.select(*numeric_cols)
df_numeric.show()

ينتج عن هذه العملية إطار بيانات يضم فقط أعمدة points وassists وrebounds بصورة آلية تماماً. تُبرز هذه التقنية قوة الربط بين البيانات الوصفية (Metadata) ومنطق الاستعلام الموزع، مما يتيح بناء نماذج تعلم آلي قادرة على التكيف مع المخططات البيانية الديناميكية دون الحاجة لتعديل الكود عند إضافة قياسات عددية جديدة في المستقبل.

7.2 الاحتفاظ بالأعمدة الفئوية والنصية للدراسات الاستكشافية

على الطرف المقابل للتحليلات الرقمية، تركز مراحل التحليل الاستكشافي الأولي للبيانات (Exploratory Data Analysis – EDA) على المتغيرات الفئوية والنصية لفهم التصنيفات، ودراسة التكرارات، وإجراء عمليات الترميز الأحادي (One-Hot Encoding) أو فهرسة السلاسل النصية (String Indexing). يتطلب هذا السيناريو عزل الأعمدة غير الرقمية في أطر بيانات مستقلة.

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

categorical_cols = [c for c, t in df.dtypes if t == 'string']
df_categorical = df.select(*categorical_cols)
df_categorical.show()

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

7.3 التصفية وفق معايير جودة البيانات والقيم المفقودة

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

يمكن أتمتة عملية الاحتفاظ بالأعمدة المكتملة عبر حساب نسبة القيم المفقودة في كل عمود برمجياً، ثم إسقاط أو استبعاد أي عمود يتجاوز عتبة فراغ محددة (كأن تكون أكثر من ثلاثين بالمئة مثلاً). يتم ذلك عبر تجميع دالة count مع التعبير الشرطي when(col(c).isNull(), 1) لحساب عدد السجلات الفارغة لكل حقل، ومقارنتها بالعدد الإجمالي للسجلات في إطار البيانات.

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

8. التعامل مع الهياكل المعقدة والمتداخلة في الأعمدة

8.1 الاحتفاظ بحقول فرعية محددة من نوع StructType

تتميز مجموعات البيانات الحديثة، ولا سيما الواردة من واجهات برمجة التطبيقات بصيغة JSON أو قواعد البيانات الوثائقية كـ MongoDB، باحتوائها على بنيات بيانات متداخلة ومكوكبة داخلياً عبر كائنات من نوع StructType. في هذه السيناريوهات، يتجاوز مفهوم “الاحتفاظ بالأعمدة” استخراج الحقول السطحية إلى ضرورة الغوص لاستخراج حقول فرعية داخلية (Nested Fields) وتسطيحها (Flattening).

يوفر PySpark آلية استدعاء شديدة القوة تستند إلى استخدام مشغل النقطة (Dot Notation) للوصول إلى الحقول المتداخلة داخل السلاسل النصية أو عبر كائنات col. إذا افترضنا وجود حقل رئيسي باسم location يمثل بنية هيكلية تحتوي داخلياً على city وstate، يمكن استخراج الحقل الفرعي مع الاحتفاظ بالأعمدة العادية الأخرى كالتالي:

df_nested = df.select("team", "location.city", "points")

يقوم محرك Spark باستخلاص الحقل الفرعي city وتوليده كعمود مستقل في إطار البيانات الجديد، مع الحفاظ على البيانات المرتبطة في عمودي team وpoints دون المساس بسلامة السجلات، مما يسمح بإعادة هيكلة البيانات المعقدة بسلاسة ودون الحاجة لتفكيك كلي للهيكل الأصلي.

8.2 التعامل مع أعمدة المصفوفات والخرائط المتداخلة

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

عند الحاجة لتحويل عناصر المصفوفة إلى أسطر مستقلة مع الحفاظ على بقية الأعمدة التعريفية، تُستخدم دالة الانفجار explode المستوردة من pyspark.sql.functions. يتم استدعاء هذه الدالة بالتوازي مع الأعمدة الثابتة داخل استعلام select موحد:

from pyspark.sql.functions import explode
df_exploded = df.select("team", "points", explode("championship_years").alias("championship_year"))

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

8.3 الحفاظ على الأعمدة المستخرجة وإعادة تسميتها في خطوة موحدة

عند التعامل مع الحقول المتداخلة، يُنتج استدعاء مشغل النقطة أسماء أعمدة افتراضية مركبة مثل location.city، وهي تسميات غير محبذة وتتعارض مع المعايير التسموية القياسية لمعظم مستودعات البيانات وأنظمة Apache Hive التي تحظر استخدام النقاط داخل أسماء الحقول.

تقتضي الممارسة الهندسية الفضلى دمج عمليتي الاستخراج المتداخل وإعادة التسمية في تعبير واحد لا يتجزأ، وذلك بالجمع بين دالة col والتابع alias() داخل استدعاء select نفسه:

df_flattened = df.select(
    col("team"),
    col("location.city").alias("city"),
    col("points")
)

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

9. الاعتبارات المتقدمة للأداء وتحسين كفاءة التنفيذ

9.1 مفهوم دفع الإسقاط إلى الأسفل في صيغ التخزين العمودية

تتحقق الفائدة العظمى للاحتفاظ بالأعمدة عند اقتران محرك PySpark بصيغ التخزين العمودية الحديثة مثل Apache Parquet و Apache ORC. على النقيض من الصيغ السطرية التقليدية كالـ CSV و JSON التي تفرض قراءة السطر بالكامل من القرص للوصول إلى حقل واحد، تخزن الصيغ العمودية بيانات كل عمود في كتل متجاورة ومستقلة على وسائط التخزين الفيزيائية.

عندما يكتب المطور استعلاماً يعزل حقولاً معينة مثل df.select("team", "points")، يقوم محرك التحسين Catalyst بتطبيق تقنية متقدمة تُعرف باسم “دفع الإسقاط إلى الأسفل” (Projection Pushdown). تقوم هذه التقنية بتمرير قائمة الأعمدة المستهدفة مباشرة إلى قارئ الملفات في طبقة التخزين الفيزيائي، مما يجعل المحرك يتخطى كلياً قراءة كتل الأعمدة الأخرى من القرص.

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

9.2 أثر تقليص الأعمدة على عمليات تبادل البيانات عبر الشبكة

تُعد عمليات تبادل وتوزيع البيانات بين عقد المعالجة (Data Shuffling) المرحلة الأكثر استنزافاً للطاقة الحوسبية في الحوسبة الموزعة. تحدث هذه العمليات حتماً عند تنفيذ عمليات الربط (Joins)، أو التجميع (GroupBy)، أو إزالة التكرار (Distinct)، حيث تُجبر العقد على تشفير البيانات وبثها عبر شبكة الاتصال المحلية إلى العقد الأخرى لإعادة تجميع السجلات المشتركة في أقسام (Partitions) متوافقة.

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

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

9.3 دور محرك التحسين Catalyst في تبسيط مسارات الاستعلام

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

إذا قام مطور بكتابة كود يستدعي خمس عمليات select متتالية لإعادة ترتيب الأعمدة أو إضافة تعديلات طفيفة، فإن Catalyst لا يُنفذ خمس دورات مسح للمصفوفات، بل يقوم بدمج هذه القواعد وإزالة المتغيرات الميتة (Dead Code Elimination) وتوليد خطة تنفيذ مادية موحدة ومثالية تنفذ كافة الإسقاطات في مسار وحيد.

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

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

10.1 إدارة الأخطاء البرمجية الناتجة عن عدم تطابق الأسماء

أحد الأخطاء الأكثر شيوعاً وتكراراً في مشروعات PySpark هو الخطأ الاستثنائي الناتج عن محاولة استدعاء عمود غير موجود في المخطط، والذي يُطلق برمجياً باسم AnalysisException مع رسالة واضحة تُشير إلى عدم العثور على الحقل المحدد (A column or function to be called cannot be found).

لتفادي توقف المهام الإنتاجية الطويلة بسبب هذا الخطأ، يُنصح بتطبيق آليات وقائية تفحص وجود الأعمدة المستهدفة قبل الشروع في تمريرها للاستعلام. يمكن تحقيق ذلك من خلال مقارنة المجموعات الرياضية (Set Intersection) بين قائمة الأعمدة المطلوبة وخاصية df.columns الفعلية:

required_columns = ["team", "points", "invalid_column"]
existing_columns = [c for c in required_columns if c in df.columns]
df_safe = df.select(*existing_columns)

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

10.2 معايير كتابة شيفرات برمجية نظيفة وقابلة للصيانة

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

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

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

10.3 دليل القرار البرمجي لاختيار الأسلوب الأنسب للمشروع

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

  • التمرير النصي المباشر select("col1", "col2"): يُعتمد عليه حصرياً في التحليلات الاستكشافية السريعة والمهام الفردية الصغيرة داخل نوادي التحليل المؤقتة حيث تكون الأولوية للسرعة البديهية في الكتابة.
  • استخدام كائنات الأعمدة select(col("col1")): يمثل الخيار القياسي لكافة خطوط أنابيب الإنتاج المؤتمتة، خاصة عند الحاجة لتطبيق عمليات تحويل أو إعادة تسمية (Aliasing) مرافقة أثناء عملية الاحتفاظ.
  • القوائم الديناميكية select(*columns_list): يُلجأ إليه حتماً عند بناء أطر معالجة عامة تعتمد على ملفات تكوين خارجية أو عندما يتجاوز عدد الأعمدة العشرات، وكذلك في سيناريوهات التصفية الشرطية التلقائية.
  • استراتيجية الإسقاط drop("col1"): يُفضل اعتمادها فقط عندما تكون نسبة الحقول المحذوفة ضئيلة للغاية مقارنة بالحقول المتبقية، وعند التأكد التام من استقرار وثبات المخطط ضد الانجراف المستقبلي.

خاتمة شاملة وآفاق مستقبلية

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

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

المراجع

  • Armbrust, M., Xin, R. S., Lian, C., Huai, Y., Liu, D., Bradley, J. K., Meng, X., Kaftan, T., Franklin, M. J., Ghodsi, A., & Zaharia, M. (2015). Spark SQL: Relational data processing in Spark. In Proceedings of the 2015 ACM SIGMOD International Conference on Management of Data (pp. 1383–1394). Association for Computing Machinery. https://doi.org/10.1145/2723372.2742797
  • Chambers, B., & Zaharia, M. (2018). Spark: The definitive guide: Big data processing made simple. O’Reilly Media.
  • Damji, J. S., Wenig, B., Das, T., & Lee, D. (2020). Learning Spark: Lightning-fast data analytics (2nd ed.). O’Reilly Media.
  • Zaharia, M., Chowdhury, M., Das, T., Dave, A., Ma, J., McCauley, M., Franklin, M. J., Shenker, S., & Stoica, I. (2012). Resilient distributed datasets: A fault-tolerant abstraction for in-memory cluster computing. In Presented as part of the 9th USENIX Symposium on Networked Systems Design and Implementation (NSDI 12) (pp. 15–28). USENIX.
  • Zaharia, M., Chowdhury, M., Franklin, M. J., Shenker, S., & Stoica, I. (2010). Spark: Cluster computing with working sets. In Proceedings of the 2nd USENIX Workshop on Hot Topics in Cloud Computing (HotCloud 10) (pp. 1–7). USENIX.
★

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

5.0 / 5 • 7 تقييمات

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

looti, M. (2026, أكتوبر 24). كيفية الاحتفاظ بأعمدة معينة في PySpark (مع أمثلة). عرب سايكلوجي. https://arabpsychology.com/statistics/how-to-keep-certain-columns-in-pyspark-with-examples/
looti, Mohammed. “كيفية الاحتفاظ بأعمدة معينة في PySpark (مع أمثلة).” عرب سايكلوجي, 24 أكتوبر 2026, https://arabpsychology.com/statistics/how-to-keep-certain-columns-in-pyspark-with-examples/.
looti, Mohammed. “كيفية الاحتفاظ بأعمدة معينة في PySpark (مع أمثلة).” عرب سايكلوجي. أكتوبر 24, 2026. https://arabpsychology.com/statistics/how-to-keep-certain-columns-in-pyspark-with-examples/.