Pandas: مشروع: تحليل البيانات
آخر تحديث: 2026-08-26
بعد 22 درسًا في الأدوات والتقنيات، حان الوقت لجمع كل شيء معًا. يحاكي هذا الدرس مشروعًا واقعيًا لتحليل البيانات: حيث تتلقى المهمة "تحليل سلوك المستخدمين في الشراء للربع الأول إلى الثالث"، وتتبع سير العمل الكامل من تحميل ملف CSV، واستكشاف البيانات، وتنظيفها، وهندسة الخصائص، والتجميع، وتصور البيانات، وحتى الخلاصات. في تحليل البيانات الحقيقي، يُخصص 80% من الوقت للتنظيف و20% للتحليل، لكن الخلاصات تعتمد تمامًا على ذلك الـ 20%.
1. What You Will Learn
- ❶ End-to-end analysis workflow
- ❷ Data loading and exploration
- ❸ Cleaning pipeline (pipe)
- ❹ Feature engineering
- ❺ Aggregation analysis and visualization report
2. خلفية المشروع: تحليل سلوك شراء المستخدم في التجارة الإلكترونية
(1) المهمة
تلقى تشارلي مهمة: 'حلل سلوك شراء المستخدم لدينا للربع الأول إلى الثالث (Q1-Q3). حدد المستخدمين ذوي القيمة العالية، والفئات الشائعة، واتجاهات الإنفاق، ثم قدم توصيات قابلة للتنفيذ للعمليات.'
(2) سير عمل التحليل
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"]
> **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. تحميل البيانات واستكشافها
▶ مثال
> **الإخراج:** قم بتشغيله في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) والاتباع. قد تختلف القيم الفعليّة قليلاً حسب إصدار pandas.
: تحميل البيانات وتحليلها الاستكشافي (الصعوبة ⭐⭐)
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()}")
> **الإخراج:** قم بتشغيله في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) والاتباع. قد تختلف القيم الفعليّة قليلاً حسب إصدار pandas.
4. أنابيب التنظيف
▶ مثال
> **الخرج:** التشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على مكتبة pandas مثبتة مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) والمتابعة. قد تختلف القيم الفعلي قليلاً حسب إصدار pandas.
: أنبوب تنظيف أنابيب المعالجة (الصعوبة ⭐⭐⭐)
# ============================================
# الخطوة 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()}")
> **الخرج:** التشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على مكتبة pandas مثبتة مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) والمتابعة. قد تختلف القيم الفعلي قليلاً حسب إصدار pandas.
5. هندسة الميزات والتجميع
▶ مثال
> **الخرج:** قم بتشغيله في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على مكتبة pandas مثبته مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) واتباع التعليمات. قد تختلف القيم الفعليه قليلاً حسب إصدار pandas.
: ميزات RFM + تحليل المجموعات (الصعوبة ⭐⭐⭐)
# ============================================
# الخطوات 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}")
> **الخرج:** قم بتشغيله في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على مكتبة pandas مثبته مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) واتباع التعليمات. قد تختلف القيم الفعليه قليلاً حسب إصدار pandas.
6. تقرير التصوير والاستنتاجات
▶ مثال
> **الإخراج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) واتباع التعليمات. قد تتغير القيم الفعلية قليًلا اعتمادًا على إصدار pandas.
: تقرير التصوير (الصعوبة ⭐⭐⭐)
# ============================================
# 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")
> **الإخراج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) واتباع التعليمات. قد تتغير القيم الفعلية قليًلا اعتمادًا على إصدار pandas.
7. تقرير التحقق من البيانات والجودة
▶ مثال
> **الناتج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) واتباع الخطوات. قد تختلف القيم الفعلية قليلاً حسب إصدار pandas.
: تقرير التحقق من البيانات والجودة (الصعوبة ⭐⭐)
# ============================================
# الخطوة: التحقق من البيانات وتقرير الجودة
# حساب معدل القيم المفقودة / معدل التكرارات /
# نسبة القيم الشاذة، وإنشاء تقرير الجودة
# ============================================
# 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 '⚠️ تحتاج إلى اهتمام'}")
> **الناتج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا. يرجى تثبيته محليًا (`pip install pandas`) واتباع الخطوات. قد تختلف القيم الفعلية قليلاً حسب إصدار pandas.
❓ أسئلة شائعة
f3(f2(f1(df))) أو إعادة التعيين المتكررة مثل df = df.... كلما زادت خطوات التنظيف، زاد تألق pipe.📖 ملخص
- سير عمل متكامل: تحميل، استكشاف، تنظيف، هندسة الميزات، تجميع، تصور، واستنتاج
- التحليل الاستكشافي للبيانات هو نقطة البداية: شكل/أنواع البيانات/القيم المفقودة/الوصف لبناء حدس بياناتية
- أنبوب المعالجة يبني خط تنظيف: إزالة التكرار، ملء القيم، إصلاح الأنواع، إضافة أعمدة مشتقة
- RFM هو التقسيم الكلاسيكي للمستخدمين: الحداثة (Recency) + التكرار (Frequency) + القيمة النقدية (Monetary)
- التحقق ثلاثي الخطوات: الاتساق العددي، المصداقية المنطقية، التحقق المتبادل
- هيكل التقرير: الاستنتاج أولاً، النتائج المدعومة بالبيانات، التوصيات القابلة للتنفيذ
📝 تمارين
- أساسي (الصعوبة ⭐): قم بتحميل بيانات التجارة الإلكترونية المحاكاة، أكمل تحليل البيانات الاستكشافي (الشكل/القيم المفقودة/الوصف)، واكتب 3 ملاحظات حول جودة البيانات.
- متوسط (الصعوبة ⭐⭐): قم ببناء خط أنابيب تنظيف بخطوات 3 (إزالة التكرارات، الملء، إصلاح الأنواع)، ثم تحقق من أن القيم المفقودة = 0 والتكرارات = 0 بعد التنظيف.
- تحدي (الصعوبة ⭐⭐⭐): أكمل تحليلًا شاملاً من البداية إلى النهاية: التحميل، تنظيف خط الأنابيب، ميزات RFM، تصنيف الشهور/الفئات، وإصدار تقرير خاتمة وتوصيات.