طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 303 · من الفكرة إلى المنتج (٣): بيانات وتنبّؤ
الدرس 2 · الوحدة 1: تأطير المشكلة والبيانات

المحطّة ٢: جمع البيانات وتنظيفها

من الفوضى إلى جدولٍ نظيف: حلّل، نظّف، وعالج الناقص بوعي. ⏱ نحو 24 دقيقة.

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

١البيانات الخامّ فوضى

البيانات في الواقع نادرًا ما تأتي نظيفة: فراغاتٌ زائدة، قيَمٌ ناقصة، أنواعٌ مختلطة (أرقامٌ مخزّنةٌ نصًّا). قبل أيّ تحليلٍ لا بدّ من التنظيف — وهو غالبًا أطول خطوةٍ في مشروع البيانات (تعلّمت أساسه في 244).

بياناتنا الخامّ (كأنها من ملفّ CSV): اسمٌ وثلاث درجاتٍ ونسبة حضور. لاحظ المشكلات: فراغاتٌ حول بعض الأسماء، ودرجةٌ ثالثةٌ مفقودةٌ عند طالبين:

main.py
raw = """name,g1,g2,g3,attendance سعود ,70,65,80,0.9نورة,55,40,60,0.6خالد ,90,85,88,0.95ريم,50,45,,0.5فهد,60,62,,0.8""" lines = raw.strip().split("\n")print("عدد الأسطر (مع الترويسة):", len(lines))print("الترويسة:", lines[0])print("أول سطر بيانات:", lines[1])
Shell×
>>> %Run main.py
عدد الأسطر (مع الترويسة): 6
الترويسة: name,g1,g2,g3,attendance
أول سطر بيانات: سعود ,70,65,80,0.9
>>>

٢التحليل إلى صفوفٍ منظّمة

نحوّل كل سطرٍ إلى قاموس مفاتيحه أسماء الأعمدة (بنية تعلّمتها في 111 و101). ونعالج المشكلات أثناء ذلك: .strip() للفراغات، وتحويل الأرقام بـ int وfloat:

main.py
raw = """name,g1,g2,g3,attendance سعود ,70,65,80,0.9نورة,55,40,60,0.6خالد ,90,85,88,0.95ريم,50,45,,0.5فهد,60,62,,0.8""" lines = raw.strip().split("\n")rows = []for line in lines[1:]:                 # نتجاوز الترويسة    name, g1, g2, g3, att = line.split(",")    rows.append({        "name": name.strip(),          # نزيل الفراغات        "grades": [g1, g2, g3],        # نصوص الآن، ننظّفها بعد قليل        "attendance": float(att),    }) print("عدد الطلاب:", len(rows))print("أول طالب:", rows[0]["name"], "— حضور", rows[0]["attendance"])
Shell×
>>> %Run main.py
عدد الطلاب: 5
أول طالب: سعود — حضور 0.9
>>>

٣معالجة القيَم الناقصة

الدرجة الثالثة مفقودةٌ عند «ريم» و«فهد» (قيمةٌ فارغة بين الفاصلتين). قرارنا الصريح: نحسب المتوسّط من الدرجات الموجودة فقط (لا نعدّ المفقود صفرًا — فذلك يظلم الطالب). نحوّل ما ليس فارغًا إلى عددٍ ونتجاهل الفارغ:

main.py
cells = ["50", "45", ""]            # درجات طالبٍ فيها واحدةٌ مفقودةgrades = [int(g) for g in cells if g.strip() != ""]print("الدرجات الموجودة:", grades)print("عددها:", len(grades))
Shell×
>>> %Run main.py
الدرجات الموجودة: [50, 45]
عددها: 2
>>>

توقّع وتحقّق

ما الذي يزيل الفراغات الزائدة حول نصّ؟

كيف نتجاهل القيمة المفقودة "" عند حساب المتوسّط؟

لماذا نحوّل "70" إلى int؟

لماذا نتجاوز lines[0]؟

الخلاصة

تحدٍّ برمجي: تنظيف بيانات الطلاب

سهل

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

المطلوب:
  • تجاوز سطر الترويسة.
  • نظّف الاسم بـ .strip()، وحوّل الدرجات الموجودة إلى int متجاهلًا الفارغ.
  • اطبع عدد الطلاب: 5، ثم لكل طالبٍ سطرًا الاسم: عدد الدرجات.

ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:

main.py
raw = """name,g1,g2,g3,attendance سعود ,70,65,80,0.9نورة,55,40,60,0.6خالد ,90,85,88,0.95ريم,50,45,,0.5فهد,60,62,,0.8""" lines = raw.strip().split("\n")# أكمل: حوّل الأسطر إلى صفوفٍ منظّفة، ثم اطبع المطلوب
المطلوب×
عدد الطلاب: 5
سعود: 3
نورة: 3
خالد: 3
ريم: 2
فهد: 2
💡 تلميح 1
رشّح الفارغ: [int(g) for g in [g1,g2,g3] if g.strip() != ""].
💡 تلميح 2
اطبع العدد أوّلًا، ثم مُرّ على الصفوف واطبع f"{name}: {len(grades)}".

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

main.py
raw = """name,g1,g2,g3,attendance سعود ,70,65,80,0.9نورة,55,40,60,0.6خالد ,90,85,88,0.95ريم,50,45,,0.5فهد,60,62,,0.8""" lines = raw.strip().split("\n")rows = []for line in lines[1:]:    name, g1, g2, g3, att = line.split(",")    grades = [int(g) for g in [g1, g2, g3] if g.strip() != ""]    rows.append({"name": name.strip(), "grades": grades, "attendance": float(att)}) print("عدد الطلاب:", len(rows))for r in rows:    print(f"{r['name']}: {len(r['grades'])}")

🐞 لاحظت خطأً في هذا الدرس؟ أبلغني بالبريد

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس