التحقق من المخطط والتأكيدات
اكتب فحوصات تأكيد لنطاقات الأعمدة وقيود عدم الإفراغ والمفاتيح الفريدة، وشغّلها في بداية كل مسار معالجة.
التحقق من المخطط والتأكيدات درس مجاني في Pandas & NumPy Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Pandas & NumPy Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.
أهمية التحقق من مخطط البيانات
تعالج معالجة البيانات البيانات الجديدة تلقائيًا، وغالبًا من دون مراجعة بشرية. إذا تغيّر مخطط ملف الإدخال — كإعادة تسمية عمود، أو تغيّر تنسيق تاريخ، أو ظهور فئة جديدة — فيجب أن تفشل بوضوح بدلًا من إنتاج مخرجات خاطئة من دون تنبيه. ويمثل التحقق من مخطط البيانات باستخدام عمليات التحقق الآلية الآليةَ التي تفرض العقود بين منتجي البيانات ومستهلكيها، وتكشف المشكلات في أقرب وقت ممكن.
import pandas as pd
import numpy as np
df = pd.read_parquet('sales_treated.parquet')
print('Loaded:', df.shape)
print(df.dtypes)التحقق من الأعمدة المطلوبة
أبسط عمليات التحقق الأساسية هي التأكد من وجود جميع الأعمدة المطلوبة. خزّن مجموعة الأعمدة المتوقعة في الإعدادات، وتأكد من أنها مجموعة جزئية من الأعمدة الفعلية. يكشف هذا التحقق عمليات إعادة التسمية والحذف فورًا عند بدء المعالجة، قبل أن يحاول أي كود لاحق الوصول إلى أعمدة مفقودة ويؤدي إلى ظهور KeyError مربك في مرحلة متأخرة من المعالجة.
REQUIRED_COLUMNS = {'order_id', 'order_date', 'customer_id',
'product', 'category', 'quantity', 'unit_price', 'revenue'}
missing = REQUIRED_COLUMNS - set(df.columns)
assert not missing, f'Missing required columns: {missing}'
print('All required columns present.')عمليات التحقق من أنواع بيانات الأعمدة
بعد التحقق من الأعمدة المطلوبة، تحقّق من أنواع بياناتها. يشير تحميل عمود التاريخ على هيئة object إلى عدم استدعاء pd.to_datetime(). وغالبًا ما يعني تخزين عمود المعرّف على هيئة float بدلًا من int64 وجود قيم NaN منعت التخزين كأعداد صحيحة. اكتب عمليات التحقق من النوع باستخدام assert df['col'].dtype == expected_type للأعمدة الأكثر أهمية.
assert pd.api.types.is_datetime64_any_dtype(df['order_date']), \
'order_date must be datetime'
assert pd.api.types.is_numeric_dtype(df['revenue']), \
'revenue must be numeric'
assert df['order_id'].dtype == object or pd.api.types.is_integer_dtype(df['order_id']), \
'order_id must be string or int'
print('Dtype checks passed.')قيود القيم غير الفارغة
يجب ألا تكون الأعمدة الأساسية مثل order_id وorder_date وrevenue فارغة مطلقًا. تحقّق من df['col'].notna().all() لكل منها. ولجعل رسالة التحقق قابلة للتنفيذ، أدرج عدد القيم الفارغة حتى يعرف مشغّل المعالجة حجم المشكلة، بدلًا من معرفة أن عملية تحقق ما قد فشلت فحسب.
NOT_NULL_COLS = ['order_id', 'order_date', 'revenue', 'customer_id']
for col in NOT_NULL_COLS:
null_count = df[col].isna().sum()
assert null_count == 0, f'{col} has {null_count} null values'
print('Non-null checks passed.')التحقق من نطاقات الأعمدة الرقمية
غالبًا ما تكون للأعمدة الرقمية نطاقات صالحة تحددها قواعد العمل. يجب ألا تكون الإيرادات سالبة. ويجب أن تكون الكمية عددًا صحيحًا موجبًا. كما يجب أن يكون سعر الوحدة أكبر من الصفر. تحقّق من هذه القيود صراحةً؛ فمرور صف ذي إيرادات سالبة سيؤدي إلى تقليل الإجماليات في كل عملية تجميع لاحقة من دون ظهور أي خطأ. تكشف عمليات التحقق من النطاق أخطاء إدخال البيانات وأخطاء الأنظمة المصدرية مبكرًا.
assert (df['revenue'] >= 0).all(), 'Negative revenue found'
assert (df['quantity'] > 0).all() or df['is_return'].any(), \
'Non-positive quantity without return flag'
assert (df['unit_price'] > 0).all(), 'Zero or negative unit price found'
print('Range checks passed.')عمليات التحقق من المفاتيح الفريدة
بعد إزالة التكرارات، يجب أن تكون قيم order_id فريدة. تحقّق من df['order_id'].is_unique للتأكد من الحفاظ على هذا الثابت في كل تشغيل للمعالجة. تشير انتهاكات التفرد بعد إزالة التكرارات إلى وجود خلل في منطق إزالة التكرارات، أو إلى مصدر بيانات جديد لم يُنظَّف قبل دمجه في مجموعة البيانات الأساسية.
assert df['order_id'].is_unique, \
f'order_id not unique: {df.duplicated(subset=["order_id"]).sum()} duplicates'
print('Uniqueness check passed.')عمليات التحقق من قيم الفئات
بالنسبة إلى الأعمدة التي تحتوي على مجموعة محدودة من القيم الصالحة — مثل region أو category — تحقّق من انتماء كل قيمة إلى المجموعة المسموح بها. يكشف ذلك القيم الدخيلة التي قد تظهر بعد ترحيل النظام أو تغيير في إدخال البيانات من المصدر. عرّف المجموعات الصالحة في إعدادات المعالجة ليسهل تحديثها عند توسع النشاط إلى مناطق جديدة.
VALID_REGIONS = {'North', 'South', 'East', 'West', 'Central'}
VALID_CATEGORIES = {'electronics', 'apparel', 'home', 'sports', 'beauty', 'other'}
assert df['region'].isin(VALID_REGIONS).all(), \
f'Invalid regions: {df[~df["region"].isin(VALID_REGIONS)]["region"].unique()}'
assert df['category'].isin(VALID_CATEGORIES).all(), \
'Invalid categories found'
print('Categorical checks passed.')عمليات التحقق من نطاق التاريخ
تحقّق من وقوع جميع التواريخ ضمن الفترة المتوقعة لمجموعة البيانات. فوجود طلب مؤرخ في المستقبل أمر مستحيل، بينما يشير طلب مؤرخ قبل تأسيس الشركة إلى سجل تالف. عرّف MIN_DATE وMAX_DATE في الإعدادات، وتحقّق من وقوع العمود ضمن الحدين. يكشف ذلك أيضًا تواريخ بداية حقبة Unix (1970-01-01) الناتجة عن تحويلات الطوابع الزمنية غير الصحيحة.
MIN_DATE = pd.Timestamp('2020-01-01')
MAX_DATE = pd.Timestamp('today')
assert (df['order_date'] >= MIN_DATE).all(), 'Date before minimum found'
assert (df['order_date'] <= MAX_DATE).all(), 'Future date found'
print(f'Date range: {df["order_date"].min()} to {df["order_date"].max()}')حاجز حماية عدد الصفوف
يمثل التغيّر المفاجئ في عدد الصفوف مقارنةً بالتشغيل السابق للمعالجة إشارة قوية إلى وجود مشكلة في المصدر. خزّن عدد صفوف التشغيل السابق في ملف إعدادات، وتحقّق من وقوع العدد الجديد ضمن نطاق سماح — مثل أن يكون في حدود ±20% من العدد التاريخي. وتشير مجموعة بيانات فقدت 50% من صفوفها بين تشغيلين، على الأرجح، إلى تعطل في تصدير البيانات.
EXPECTED_MIN_ROWS = 5000
EXPECTED_MAX_ROWS = 200000
assert EXPECTED_MIN_ROWS <= len(df) <= EXPECTED_MAX_ROWS, \
f'Row count {len(df)} outside expected range [{EXPECTED_MIN_ROWS}, {EXPECTED_MAX_ROWS}]'
print(f'Row count check passed: {len(df)} rows')تجميع عمليات التحقق في دالة Validate
اجمع جميع عمليات التحقق في دالة واحدة هي validate(df)، بحيث يمكن استدعاؤها في بداية كل مرحلة من مراحل المعالجة. تُطلق كل عملية تحقق AssertionError مع رسالة وصفية عند فشلها. يجعل هذا النمط المعالجة موثقة ذاتيًا؛ فدالة التحقق تمثل عقد مخطط البيانات القابل للقراءة آليًا لإطار البيانات في تلك المرحلة.
def validate_sales_df(df):
assert not (REQUIRED_COLUMNS - set(df.columns)), 'Missing columns'
assert df['order_id'].is_unique, 'Duplicate order IDs'
assert (df['revenue'] >= 0).all(), 'Negative revenue'
assert df['region'].isin(VALID_REGIONS).all(), 'Invalid region'
print(f'Validation passed: {len(df)} rows, {len(df.columns)} columns')
validate_sales_df(df)تسجيل حالات فشل التحقق بسلاسة
في معالجات الإنتاج، يُعدّ توقف التنفيذ بسبب assert مقبولًا أثناء التطوير، لكنه غير مرغوب فيه في مهمة مجدولة. استبدل عمليات التحقق المجردة بكتل try/except AssertionError التي تسجل رسالة الخطأ، وترسل تنبيهًا اختياريًا قبل الخروج. يتيح ذلك لنظام المراقبة التقاط سبب الفشل بدلًا من الاكتفاء بتتبّع استثناء غير معالج.
import logging
logging.basicConfig(level=logging.INFO)
def validate_with_logging(df):
checks = [
(lambda d: d['order_id'].is_unique, 'Duplicate order IDs'),
(lambda d: (d['revenue'] >= 0).all(), 'Negative revenue found'),
]
for check_fn, msg in checks:
try:
assert check_fn(df), msg
except AssertionError as e:
logging.error(f'VALIDATION FAILED: {e}')
raise
validate_with_logging(df)
print('All checks passed.')تحقق سريع
اختبر مدى فهمك لمفاهيم تحليل البيانات التي تناولها هذا الدرس.
مراجعة الدرس
تعلّمت في هذا الدرس: التحقق من الأعمدة المطلوبة وأنواع البيانات والقيود على القيم غير الفارغة وصحة النطاقات، والتحقق من المفاتيح الفريدة وقيم الفئات ونطاقات التواريخ، وتجميع جميع عمليات التحقق في دالة validate() قابلة لإعادة الاستخدام مع التسجيل. ننتقل بعد ذلك إلى استكشاف التجميعات المخصصة باستخدام apply() على الأعمدة والصفوف.
الأسئلة الشائعة
هل درس «التحقق من المخطط والتأكيدات» مجاني؟
نعم — نص درس «التحقق من المخطط والتأكيدات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Pandas & NumPy Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.
ماذا ستتعلم في «التحقق من المخطط والتأكيدات»؟
اكتب فحوصات تأكيد لنطاقات الأعمدة وقيود عدم الإفراغ والمفاتيح الفريدة، وشغّلها في بداية كل مسار معالجة. تتمرن على Pandas & NumPy Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Pandas & NumPy Academy؟
لا تُشترط خبرة سابقة. Pandas & NumPy Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «التحقق من المخطط والتأكيدات»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Pandas & NumPy Academy هذا؟
نعم. كل درس في Pandas & NumPy Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- اكتشاف التكرارات وإزالتها
- اكتشاف القيم الشاذة ومعالجتها
- توحيد الفئات غير المتسقة
- التحقق من المخطط والتأكيدات