0Pricing
Pandas & NumPy Academy · درس

اكتشاف القيم المفقودة

استخدم isna() وnotna() وisnull() للعثور على مواضع NaN في Series أو DataFrame، ولعدّ القيم المفقودة في كل عمود.

اكتشاف القيم المفقودة درس مجاني في Pandas & NumPy Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Pandas & NumPy Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.

ما القيم المفقودة في Pandas؟

تُمثَّل القيمة المفقودة في Pandas بالرمز NaN (ليس رقمًا) في الأعمدة الرقمية، وبالقيمة None أو pd.NaT في أعمدة التاريخ والوقت. تُعدّ البيانات المفقودة شائعة في مجموعات البيانات الواقعية، فقد تكون السجلات غير مكتملة، أو تتعطل المستشعرات، أو تؤدي عمليات الدمج إلى صفوف غير متطابقة. ويُعد اكتشاف القيم المفقودة دائمًا الخطوة الأولى في أي سير عمل لتنظيف البيانات.

توحّد Pandas القيم None وfloat('nan') وnumpy.nan في تمثيل NaN الداخلي نفسه للأعمدة الرقمية.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'name': ['Alice', None, 'Carol'],
    'age': [25, np.nan, 30],
    'salary': [50000.0, 60000.0, np.nan]
})
print(df)
#     name   age   salary
# 0  Alice  25.0  50000.0
# 1   None   NaN  60000.0
# 2  Carol  30.0      NaN

isna() وisnull()

إن isna() وisnull() متطابقان تمامًا — فكلاهما يعيد DataFrame أو Series بالشكل نفسه، مملوءًا بالقيمة True حيث تكون القيمة مفقودة، وبالقيمة False في المواضع الأخرى. توفر Pandas الاسمين لمجرد تفضيل المستخدم. ويمكن استخدام النتيجة مباشرةً كقناع منطقي للتصفية أو لإجراء مزيد من العمليات الحسابية.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'A': [1, np.nan, 3],
    'B': [np.nan, 2, np.nan]
})

print(df.isna())
#        A      B
# 0  False   True
# 1   True  False
# 2  False   True

# Both are identical
print((df.isna() == df.isnull()).all().all())  # True

استخدام notna() للعثور على القيم غير المفقودة

إن notna() (ويُعرف أيضًا بالاسم البديل notnull()) هو عكس isna() — إذ يعيد True حيث تكون القيم موجودة، وFalse حيث تكون مفقودة. يفيد ذلك عندما تريدون تصفية الصفوف التي تحتوي على قيمة في عمود مهم، مثل اشتراط ألا يكون المعرّف الأساسي أو المتغير الهدف NaN.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'id': [1, 2, 3],
    'email': ['a@x.com', None, 'c@x.com']
})

# Keep only rows where email is present
with_email = df[df['email'].notna()]
print(with_email)
#    id    email
# 0   1  a@x.com
# 2   3  c@x.com

عدّ القيم المفقودة لكل عمود

يؤدي استدعاء .isna().sum() على DataFrame إلى جمع قيم True (التي تساوي 1) عمودًا تلو الآخر، ما يعطيكم عدد القيم المفقودة في كل عمود. وهذه أهم خطوة أولى لفهم جودة مجموعة بيانات جديدة، إذ توضح لكم الأعمدة التي تحتاج إلى معالجة.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'name': ['Alice', None, 'Carol', None],
    'age': [25, np.nan, 30, 22],
    'salary': [50000, 60000, np.nan, np.nan]
})

missing_counts = df.isna().sum()
print(missing_counts)
# name      2
# age       1
# salary    2
# dtype: int64

نسبة القيم المفقودة لكل عمود

يكون العدد المطلق لقيم NaN أقل فائدة من نسبة القيم المفقودة لأنها تتناسب مع حجم مجموعة البيانات. يؤدي تقسيم isna().sum() على إجمالي عدد الصفوف (أو استدعاء isna().mean()) إلى الحصول على الكسر المفقود، ويمكنكم ضربه في 100 للحصول على النسبة المئوية. غالبًا ما تتطلب الأعمدة التي تزيد نسبة القيم المفقودة فيها على 30–50% اتخاذ قرار بشأن الاحتفاظ بها أصلًا.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'A': [1, np.nan, 3, np.nan, 5],
    'B': [np.nan, 2, np.nan, 4, 5],
    'C': [1, 2, 3, 4, 5]
})

missing_pct = (df.isna().mean() * 100).round(1)
print(missing_pct)
# A    40.0
# B    40.0
# C     0.0
# dtype: float64

جدول ملخص القيم المفقودة

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

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'col_a': [1, np.nan, 3],
    'col_b': [np.nan, np.nan, 3],
    'col_c': [1, 2, 3]
})

summary = pd.DataFrame({
    'missing_count': df.isna().sum(),
    'missing_pct': (df.isna().mean() * 100).round(1),
    'dtype': df.dtypes
}).sort_values('missing_pct', ascending=False)
print(summary)
#         missing_count  missing_pct   dtype
# col_b               2         66.7  float64
# col_a               1         33.3  float64
# col_c               0          0.0  float64

عدّ القيم المفقودة على مستوى الصف

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

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'a': [1, np.nan, np.nan],
    'b': [np.nan, 2, np.nan],
    'c': [3, 4, np.nan]
})

# Count NaN per row
df['missing_count'] = df.isna().sum(axis=1)
print(df)
#      a    b    c  missing_count
# 0  1.0  NaN  3.0              1
# 1  NaN  2.0  4.0              1
# 2  NaN  NaN  NaN              3

تصفية الصفوف التي تحتوي على بعض القيم المفقودة أو كلها

استخدموا df[df.isna().any(axis=1)] للعثور على الصفوف التي تحتوي على قيمة NaN واحدة على الأقل، أو df[df.isna().all(axis=1)] للعثور على الصفوف التي تكون كل قيمها NaN. تساعدكم هذه المرشحات في عزل السجلات التي تسبب مشكلات لفحصها قبل تحديد كيفية معالجتها.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'x': [1, np.nan, np.nan],
    'y': [2, 3, np.nan],
    'z': [4, 5, np.nan]
})

# Rows with at least one NaN
has_any_nan = df[df.isna().any(axis=1)]
print('Any NaN:\n', has_any_nan)

# Rows where all values are NaN
all_nan = df[df.isna().all(axis=1)]
print('All NaN:\n', all_nan)
#      x    y    z
# 2  NaN  NaN  NaN

التحقق من NaN في عمود محدد

لإجراء فحص سريع لعمود واحد، استدعوا df['col'].isna().sum() أو استخدموا df['col'].isna().any() للحصول على قيمة منطقية واحدة (True إذا وُجدت أي قيمة NaN). تفيد هذه الأسطر البرمجية المختصرة داخل عمليات التحقق من صحة البيانات أو عبارات التسجيل في خط أنابيب.

import pandas as pd
import numpy as np

df = pd.DataFrame({'price': [10.0, np.nan, 30.0, np.nan, 50.0]})

print('NaN count in price:', df['price'].isna().sum())  # 2
print('Any NaN in price?', df['price'].isna().any())    # True
print('All present?', df['price'].notna().all())         # False

تصوير القيم المفقودة باستخدام خريطة حرارية

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

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

np.random.seed(0)
df = pd.DataFrame(
    np.where(np.random.rand(20, 5) > 0.7, np.nan, np.random.randn(20, 5)),
    columns=['A', 'B', 'C', 'D', 'E']
)

# Heatmap of missing values
sns.heatmap(df.isna(), cbar=False, yticklabels=False)
plt.title('Missing Value Pattern')
plt.tight_layout()
plt.savefig('missing_heatmap.png')
print('Saved missing_heatmap.png')

استخدام info() لإجراء فحص سريع للقيم المفقودة

تطبع df.info() ملخصًا موجزًا يتضمن عدد القيم غير الفارغة لكل عمود. وهذه أسرع طريقة لاكتشاف الأعمدة التي تحتوي على قيم مفقودة في مجموعة بيانات جديدة: فأي عمود يقل فيه عدد القيم غير الفارغة عن إجمالي عدد الصفوف يحتوي على قيم NaN. كما يعرض dtype واستخدام الذاكرة.

import pandas as pd
import numpy as np

df = pd.DataFrame({
    'id': [1, 2, 3, 4, 5],
    'age': [25, np.nan, 30, np.nan, 22],
    'salary': [50000, 60000, np.nan, 70000, 80000]
})

df.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 5 entries, 0 to 4
# Data columns (total 3 columns):
#  #   Column  Non-Null Count  Dtype
# ---  ------  --------------  -----
#  0   id      5 non-null      int64
#  1   age     3 non-null      float64
#  2   salary  4 non-null      float64

تحقق سريع

اختبروا مدى فهمكم لاكتشاف القيم المفقودة في Pandas.

مراجعة الدرس

تعلّمتم في هذا الدرس أن: isna() وisnull() متطابقان ويعيدان أقنعة منطقية لمواضع القيم المفقودة، وأن isna().sum() يعدّ قيم NaN لكل عمود، بينما يعطي isna().mean()*100 نسبة القيم المفقودة. استخدموا df.info() للحصول على نظرة عامة سريعة، وisna().any(axis=1) للعثور على الصفوف التي تحتوي على قيمة NaN واحدة على الأقل. بعد ذلك سنتناول حذف القيم المفقودة باستخدام dropna().

الأسئلة الشائعة

هل درس «اكتشاف القيم المفقودة» مجاني؟

نعم — نص درس «اكتشاف القيم المفقودة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Pandas & NumPy Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.

ماذا ستتعلم في «اكتشاف القيم المفقودة»؟

استخدم isna() وnotna() وisnull() للعثور على مواضع NaN في Series أو DataFrame، ولعدّ القيم المفقودة في كل عمود. تتمرن على Pandas & NumPy Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Pandas & NumPy Academy؟

لا تُشترط خبرة سابقة. Pandas & NumPy Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «اكتشاف القيم المفقودة»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Pandas & NumPy Academy هذا؟

نعم. كل درس في Pandas & NumPy Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. اكتشاف القيم المفقودة
  2. حذف القيم المفقودة
  3. ملء القيم المفقودة
  4. الاستيفاء والتعويض المتقدم
← العودة إلى Pandas & NumPy Academy