Pandas: مشروع: تحليل البيانات

آخر تحديث: 2026-08-26

بعد 22 درسًا في الأدوات والتقنيات، حان الوقت لجمع كل شيء معًا. يحاكي هذا الدرس مشروعًا واقعيًا لتحليل البيانات: حيث تتلقى المهمة "تحليل سلوك المستخدمين في الشراء للربع الأول إلى الثالث"، وتتبع سير العمل الكامل من تحميل ملف CSV، واستكشاف البيانات، وتنظيفها، وهندسة الخصائص، والتجميع، وتصور البيانات، وحتى الخلاصات. في تحليل البيانات الحقيقي، يُخصص 80% من الوقت للتنظيف و20% للتحليل، لكن الخلاصات تعتمد تمامًا على ذلك الـ 20%.

⚠️ ملاحظة: يجب تشغيل الكود أدناه في بيئة بايثون محلية.

1. What You Will Learn


2. خلفية المشروع: تحليل سلوك شراء المستخدم في التجارة الإلكترونية

(1) المهمة

تلقى تشارلي مهمة: 'حلل سلوك شراء المستخدم لدينا للربع الأول إلى الثالث (Q1-Q3). حدد المستخدمين ذوي القيمة العالية، والفئات الشائعة، واتجاهات الإنفاق، ثم قدم توصيات قابلة للتنفيذ للعمليات.'

(2) سير عمل التحليل

100%
graph TB
    A["1. Load Data"] --> B["2. Explore (EDA)"]
    B --> C["3. Cleaning Pipeline"]
    C --> D["4. Feature Engineering"]
    D --> E["5. Group Aggregation"]
    E --> F["6. Visualization Report"]
    F --> G["7. Conclusions & Recommendations"]
TEXT 📖 للعرض فقط
> **Output:** Run in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed. Please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on the pandas version.

3. تحميل البيانات واستكشافها

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** قم بتشغيله في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) والاتباع. قد تختلف القيم الفعليّة قليلاً حسب إصدار pandas.

: تحميل البيانات وتحليلها الاستكشافي (الصعوبة ⭐⭐)

PYTHON
import pandas as pd
import numpy as np

# ============================================
# الخطوة 1-2: التحميل والاستكشاف
# ============================================

# محاكاة بيانات التجارة الإلكترونية (في المشروع الحقيقي: pd.read_csv)
np.random.seed(42)
n = 2000
users = pd.DataFrame({
    'user_id': range(1, n + 1),
    'name': [f'User_{i:04d}' for i in range(1, n + 1)],
    'age': np.random.randint(18, 70, n),
    'gender': np.random.choice(['M', 'F'], n),
    'city': np.random.choice(['NYC', 'LA', 'Chicago', 'Houston', 'Phoenix'], n),
    'join_date': pd.to_datetime(np.random.choice(
        pd.date_range('2023-01-01', '2024-09-30'), n
    ))
})

orders = pd.DataFrame({
    'order_id': [f'O{i:06d}' for i in range(1, 5001)],
    'user_id': np.random.randint(1, n + 1, 5000),
    'product_id': np.random.randint(1, 51, 5000),
    'category': np.random.choice(['Electronics', 'Clothing', 'Home', 'Sports', 'Books'], 5000),
    'amount': np.round(np.random.exponential(100, 5000), 2),
    'quantity': np.random.randint(1, 5, 5000),
    'order_date': pd.to_datetime(np.random.choice(
        pd.date_range('2024-01-01', '2024-09-30'), 5000
    ))
})

# إدخال مشاكل جودة البيانات
orders.loc[np.random.choice(5000, 200, replace=False), 'amount'] = np.nan
orders.loc[np.random.choice(5000, 100, replace=False), 'category'] = np.nan
duplicates = orders.sample(50)
orders = pd.concat([orders, duplicates], ignore_index=True)

# التحليل الاستكشافي: الشكل، الأنواع، القيم المفقودة، التكرارات
print(f"المستخدمون: {users.shape}, الطلبات: {orders.shape}")
print(f"\nالقيم المفقودة لكل عمود:\n{orders.isnull().sum()}")
print(f"\nالطلبات المكررة: {orders.duplicated(subset='order_id').sum()}")
print(f"\nنطاق التاريخ: من {orders['order_date'].min()} إلى {orders['order_date'].max()}")
print(f"\nإحصائيات المبالغ:\n{orders['amount'].describe()}")
TEXT 📖 للعرض فقط
> **الإخراج:** قم بتشغيله في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) والاتباع. قد تختلف القيم الفعليّة قليلاً حسب إصدار pandas.

4. أنابيب التنظيف

▶ مثال

TEXT 📖 للعرض فقط
> **الخرج:** التشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على مكتبة pandas مثبتة مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) والمتابعة. قد تختلف القيم الفعلي قليلاً حسب إصدار pandas.

: أنبوب تنظيف أنابيب المعالجة (الصعوبة ⭐⭐⭐)

PYTHON
# ============================================
# الخطوة 3: أنبوب التنظيف (pipe)
# ============================================

def remove_duplicates(df):
    """إزالة الطلبات المكررة، مع الاحتفاظ بالأحدث"""
    before = len(df)
    df = df.drop_duplicates(subset='order_id', keep='last')
    print(f"  الدuplicates تمت إزالتها: {before - len(df)}")
    return df

def fill_missing(df):
    """ملء القيم المفقودة باستراتيجيات مناسبة"""
    df = df.copy()
    # ملء المبلغ بالمتوسط لكل فئة
    df['amount'] = df.groupby('category')['amount'].transform(
        lambda x: x.fillna(x.median())
    )
    # ملء الفئة بالقيمة الأكثر تكراراً
    df['category'] = df.fillna({'category': df['category'].mode()[0]})
    return df

def fix_types(df):
    """إصلاح أنواع البيانات"""
    df = df.copy()
    df['order_date'] = pd.to_datetime(df['order_date'])
    df['category'] = df['category'].astype('category')
    return df

def add_derived(df):
    """إضافة أعمدة مشتقة"""
    df = df.copy()
    df['total_price'] = df['amount'] * df['quantity']
    df['month'] = df['order_date'].dt.to_period('M')
    return df

# تنفيذ أنبوب المعالجة
clean_orders = (orders
    .pipe(remove_duplicates)
    .pipe(fill_missing)
    .pipe(fix_types)
    .pipe(add_derived)
)
print(f"\nالطلبات النظيفة: {clean_orders.shape}")
print(f"القيم المفقودة المتبقية: {clean_orders.isnull().sum().sum()}")
TEXT 📖 للعرض فقط
> **الخرج:** التشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على مكتبة pandas مثبتة مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) والمتابعة. قد تختلف القيم الفعلي قليلاً حسب إصدار pandas.

5. هندسة الميزات والتجميع

▶ مثال

TEXT 📖 للعرض فقط
> **الخرج:** قم بتشغيله في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على مكتبة pandas مثبته مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) واتباع التعليمات. قد تختلف القيم الفعليه قليلاً حسب إصدار pandas.

: ميزات RFM + تحليل المجموعات (الصعوبة ⭐⭐⭐)

PYTHON
# ============================================
# الخطوات 4-5: هندسة الميزات + التجميع
# ============================================

# تحليل RFM (الحداثة، التكرار، القيمة النقدية)
reference_date = clean_orders['order_date'].max() + pd.Timedelta(days=1)

rfm = clean_orders.groupby('user_id').agg(
    recency=('order_date', lambda x: (reference_date - x.max()).days),
    frequency=('order_id', 'count'),
    monetary=('total_price', 'sum')
).reset_index()

# تسجيل RFM (مبني على الأرباع)
rfm['R_score'] = pd.qcut(rfm['recency'], 4, labels=[4, 3, 2, 1]).astype(int)
rfm['F_score'] = pd.qcut(rfm['frequency'].rank(method='first'), 4, labels=[1, 2, 3, 4]).astype(int)
rfm['M_score'] = pd.qcut(rfm['monetary'].rank(method='first'), 4, labels=[1, 2, 3, 4]).astype(int)
rfm['RFM_score'] = rfm['R_score'] + rfm['F_score'] + rfm['M_score']

# تقسيم المستخدمين إلى شرائح
rfm['segment'] = pd.cut(rfm['RFM_score'], bins=[0, 5, 8, 10, 12],
                         labels=['At-Risk', 'Average', 'Good', 'Champions'])

print("=== شرائح المستخدمين ===")
print(rfm['segment'].value_counts())

# اتجاه الإيرادات الشهرية
monthly_rev = clean_orders.groupby('month')['total_price'].sum()
print(f"\n=== الإيرادات الشهرية ===\n{monthly_rev}")

# تحليل الفئات
cat_stats = clean_orders.groupby('category').agg(
    orders=('order_id', 'count'),
    revenue=('total_price', 'sum'),
    avg_amount=('amount', 'mean')
).sort_values('revenue', ascending=False)
print(f"\n=== إحصائيات الفئات ===\n{cat_stats}")
TEXT 📖 للعرض فقط
> **الخرج:** قم بتشغيله في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على مكتبة pandas مثبته مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) واتباع التعليمات. قد تختلف القيم الفعليه قليلاً حسب إصدار pandas.

6. تقرير التصوير والاستنتاجات

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) واتباع التعليمات. قد تتغير القيم الفعلية قليًلا اعتمادًا على إصدار pandas.

: تقرير التصوير (الصعوبة ⭐⭐⭐)

PYTHON
# ============================================
# Step 6-7: Visualization & Conclusions
# ============================================

import matplotlib.pyplot as plt

# Summary report (no actual plots — code for local execution)
print("=" * 50)
print("  E-COMMERCE USER BEHAVIOR ANALYSIS REPORT")
print("=" * 50)

print(f"\n📊 Dataset Overview:")
print(f"  Users: {len(users):,}")
print(f"  Orders: {len(clean_orders):,}")
print(f"  Period: {clean_orders['order_date'].min().date()} to {clean_orders['order_date'].max().date()}")

print(f"\n🏆 Top Categories:")
for i, row in cat_stats.head(3).iterrows():
    print(f"  {i}: ${row['revenue']:,.0f} ({row['orders']} orders)")

print(f"\n👤 User Segments:")
for seg, count in rfm['segment'].value_counts().items():
    pct = count / len(rfm) * 100
    print(f"  {seg}: {count} ({pct:.1f}%)")

print(f"\n📈 Monthly Trend:")
monthly_growth = monthly_rev.pct_change().dropna() * 100
print(f"  Avg monthly growth: {monthly_growth.mean():.1f}%")
print(f"  Peak month: {monthly_rev.idxmax()}")
print(f"  Lowest month: {monthly_rev.idxmin()}")

print(f"\n💡 Recommendations:")
print(f"  1. Champions segment ({(rfm['segment']=='Champions').sum()} users) → VIP program")
print(f"  2. At-Risk segment ({(rfm['segment']=='At-Risk').sum()} users) → Win-back campaign")
print(f"  3. Electronics is top category → expand selection")
print(f"  4. Focus on high-F-score users for cross-selling")
TEXT 📖 للعرض فقط
> **الإخراج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) واتباع التعليمات. قد تتغير القيم الفعلية قليًلا اعتمادًا على إصدار pandas.

7. تقرير التحقق من البيانات والجودة

▶ مثال

TEXT 📖 للعرض فقط
> **الناتج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) واتباع الخطوات. قد تختلف القيم الفعلية قليلاً حسب إصدار pandas.

: تقرير التحقق من البيانات والجودة (الصعوبة ⭐⭐)

PYTHON
# ============================================
# الخطوة: التحقق من البيانات وتقرير الجودة
# حساب معدل القيم المفقودة / معدل التكرارات /
# نسبة القيم الشاذة، وإنشاء تقرير الجودة
# ============================================

# 1. تحليل معدل القيم المفقودة
missing_count = orders.isnull().sum()
missing_rate = (missing_count / len(orders) * 100).round(2)
print("=== تقرير معدل القيم المفقودة ===")
for col in missing_count[missing_count > 0].index:
    print(f"  {col}: {missing_count[col]} صفوف مفقودة ({missing_rate[col]}%)")

# 2. تحليل معدل التكرارات
dup_count = orders.duplicated(subset='order_id').sum()
dup_rate = dup_count / len(orders) * 100
print(f"\n=== تقرير معدل التكرارات ===")
print(f"  الطلبات المكررة: {dup_count} ({dup_rate:.2f}%)")

# 3. اكتشاف القيم الشاذة (المبلغ مرتفع جدًا أو منخفض جدًا)
q1 = orders['amount'].quantile(0.25)
q3 = orders['amount'].quantile(0.75)
iqr = q3 - q1
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr
outliers = orders[(orders['amount'] < lower_bound) | (orders['amount'] > upper_bound)]
outlier_rate = len(outliers) / len(orders) * 100
print(f"\n=== تقرير القيم الشاذة ===")
print(f"  القيم الشاذة في المبلغ: {len(outliers)} صفوف ({outlier_rate:.2f}%)")
print(f"  النطاق الطبيعي: ${lower_bound:.2f} ~ ${upper_bound:.2f}")

# 4. درجة جودة البيانات الإجمالية
quality_score = 100 - (missing_rate.sum() + dup_rate + outlier_rate) / 3
print(f"\n=== درجة جودة البيانات: {quality_score:.1f}/100 ===")
print(f"  {'✅ جودة جيدة' if quality_score > 90 else '⚠️ تحتاج إلى اهتمام'}")
TEXT 📖 للعرض فقط
> **الناتج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) واتباع الخطوات. قد تختلف القيم الفعلية قليلاً حسب إصدار pandas.

❓ أسئلة شائعة

س من أين يجب أن أبدأ التحليل؟
ج ابدأ بتحليل البيانات الاستكشافي (EDA). بعد التحميل، افحص الشكل/أنواع البيانات/القيم المفقودة/الوصف أولاً لبناء الحدس حول البيانات. لا تنتقل مباشرة إلى النمذجة أو الرسم. يمكن اكتشاف 80% من مشكلات التحليل خلال تحليل البيانات الاستكشافي (القيم المفقودة، القيم الشاذة، الأنواع الخاطئة). يحدد تحليل البيانات الاستكشافي الجيد جودة تحليلك.
س متى تكون البيانات نظيفة بما يكفي؟
ج نظف حتى "لا تؤثر البيانات على استنتاجاتك بعد الآن." يجب أن تكون الحقول الحرجة (المعرفات، المبالغ، التواريخ) خالية من العيوب؛ يمكن للحقول الثانوية تحمل بعض القيم المفقودة البسيطة. القاعدة العملية: 0% قيم مفقودة في الأعمدة الرئيسية، أقل من 5% في الأعمدة غير الرئيسية. التنظيف لا يتعلق بالكمال؛ بل يتعلق بإزالة الضوضاء.
س ماذا تتضمن هندسة الميزات؟
ج اشتقاق أعمدة مفيدة من البيانات الخام للتحليل. أمثلة شائعة: سمات الوقت (الشهر/الربع/يوم الأسبوع)، سمات التجميع (RFM)، سمات النسبة (هامش الربح)، والسمات الفئوية (فئة السعر). هندسة الميزات هي "إنشاء معلومات من المعرفة التجارية" -- الميزات الجيدة أكثر قيمة من النماذج المعقدة.
س كيف أتحقق من صحة نتائج التحليل؟
ج التحقق في ثلاث خطوات: (1) الاتساق العددي (إجمالي الإيرادات = مجموع الفئات = مجموع الأشهر)؛ (2) المعقولية المنطقية (لا يجب أن يتجاوز النمو الشهري 200% إلا إذا كان هناك عرض ترويجي)؛ (3) التحقق المتقاطع (احسب نفس المقياس بطرق مختلفة وأكد أنها متطابقة). إذا فشلت أي خطوة، عد بالخلف.
س كيف يجب أن أهيكل التقرير؟
ج الهيكل: الاستنتاج أولاً، ثم البيانات الداعمة، ثم التوصيات. التنسيق: ملخص تنفيذي (فقرة واحدة)، النتائج الرئيسية (3-5 نقاط مع بيانات)، تحليل مفصل (رسوم بيانية + تفسير)، توصيات (قابلة للتنفيذ). تجنب "رمي البيانات" -- كل رسم بياني يجب أن يحتوي على رؤية، وكل رؤية يجب أن تكون مدعومة ببيانات.
س ما هو RFM؟
ج الحداثة (عدد الأيام منذ آخر عملية شراء)، التكرار (عدد عمليات الشراء)، القيمة النقدية (إجمالي الإنفاق) -- ثلاثة أبعاد لقياس قيمة المستخدم. منخفضة R + عالية F + عالية M = أبطال (الأكثر قيمة)؛ عالية R + منخفضة F + منخفضة M = معرضون للخطر (على وشك الانسحاب). RFM هو أكثر طرق تقسيم المستخدمين كلاسيكية وعملية.
س ما فوائد استخدام pipe؟
ج يحول pipe تنظيف متعدد الخطوات إلى خط أنابيب مقروء من أعلى إلى أسفل حيث تكون لكل وظيفة مسؤولية واحدة، وقابلة للاختبار، وقابلة لإعادة الاستخدام. إنه أوضح من الاستدعاءات المتداخلة مثل f3(f2(f1(df))) أو إعادة التعيين المتكررة مثل df = df.... كلما زادت خطوات التنظيف، زاد تألق pipe.

📖 ملخص


📝 تمارين

  1. أساسي (الصعوبة ⭐): قم بتحميل بيانات التجارة الإلكترونية المحاكاة، أكمل تحليل البيانات الاستكشافي (الشكل/القيم المفقودة/الوصف)، واكتب 3 ملاحظات حول جودة البيانات.
  2. متوسط (الصعوبة ⭐⭐): قم ببناء خط أنابيب تنظيف بخطوات 3 (إزالة التكرارات، الملء، إصلاح الأنواع)، ثم تحقق من أن القيم المفقودة = 0 والتكرارات = 0 بعد التنظيف.
  3. تحدي (الصعوبة ⭐⭐⭐): أكمل تحليلًا شاملاً من البداية إلى النهاية: التحميل، تنظيف خط الأنابيب، ميزات RFM، تصنيف الشهور/الفئات، وإصدار تقرير خاتمة وتوصيات.

← Previous: Styling Output · Next: Project - Time Series →

Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%