body{font-family:'Amiri','Noto Naskh Arabic','Segoe UI',Arial,sans-serif;direction:rtl;text-align:right;background:#fafafa;margin:0;padding:28px} h1{margin:0 0 8px}.meta{color:#555;margin:0 0 18px} .code{background:#0b1020;color:#e6e6e6;padding:12px;border-radius:10px;overflow:auto} .stdout,.error{white-space:pre-wrap;padding:10px;border-radius:8px;border:1px solid #e5e7eb;margin-top:8px} .stdout{background:#f8fafc;color:#0b1020}.error{background:#fff1f2;color:#7f1d1d} img.fig{max-width:100%;height:auto;border:1px solid #eee;border-radius:10px;display:block;margin:12px 0 6px} .fig-cap{color:#444;margin:0 0 12px} .note{background:#f7f7ff;border:1px solid #dfe3ff;border-radius:10px;padding:10px 12px;margin:10px 0} .note-h{font-weight:700;margin-bottom:6px} .note-b{line-height:1.7}
# Arabic-ready figures + Plotly import os, pandas as pd, seaborn as sns, matplotlib.pyplot as plt os.system('apt-get -qq update'); os.system('apt-get -qq install -y fonts-amiri > /dev/null') os.system('pip -q install arabic-reshaper python-bidi plotly') import matplotlib as mpl mpl.rcParams['font.family'] = 'Amiri'; mpl.rcParams['axes.unicode_minus'] = False try: import arabic_reshaper; from bidi.algorithm import get_display def ar(s): return get_display(arabic_reshaper.reshape(str(s))) except Exception: def ar(s): return str(s) # ---------- Intro ---------- add_heading("مقدمة", level=2) add_paragraph( " ".join([ "يستعرض هذا التقرير بيانات توصيل الطعام في المملكة العربية السعودية بصورة شاملة،", "حيث يسلّط الضوء على حجم الطلبات، وتوزّعها الجغرافي بين المدن، والأنماط الزمنية الأكثر شيوعًا خلال أيام الأسبوع وأوقات الذروة.", "كما يتناول التقرير مقارنة بين أنواع المطاعم (مثل القهوة، البيتزا، المأكولات البحرية، والحلويات) وتحليل تفضيلات المستهلكين،", "إضافةً إلى قياس مستوى رضا العملاء استنادًا إلى تقييماتهم.", "وقد تم إعداد المخططات التوضيحية والجداول بالعربية، مع تفسير تفصيلي تحت كل جزء لزيادة الفهم وربط الأرقام بالواقع.", "ويأتي هذا العمل ثمرة تعاون بين منصة أرقامي وفريق PrepX، في خطوة تهدف إلى تعزيز الوعي بالبيانات", "ودعم صناع القرار ورواد الأعمال في قطاع خدمات التوصيل بالمملكة." ]) ) add_heading("أسئلة البحث", level=2) add_list([ "ما توزيع مدة التوصيل؟ وهل توجد ذيول طويلة (طلبات بطيئة جدًا)؟", "أي أنواع المطاعم تسجّل أكبر عدد من الطلبات؟", "كيف تتغير مدة التوصيل حسب تقييم العملاء؟" ]) # ---------- Load data ---------- CSV = "/content/final_output.csv" df = pd.read_csv(CSV, encoding="utf-8-sig") print("Shape:", df.shape); print("Columns:", list(df.columns)[:10]) # rename to Arabic (if not already) df.rename(columns={ 'Order Number': 'رقم الطلب','Order_City': 'المدينة','Restaurant Type': 'نوع المطعم', 'Day':'اليوم','Hour':'الساعة','Date':'التاريخ','Time':'الوقت', 'Total Bill (in Saudi Riyals)': 'قيمة الفاتورة (ريال)', 'Delivery Duration (in minutes)': 'مدة التوصيل (دقيقة)', 'Customer Rating (from 1 to 5 stars)': 'تقييم العميل (1-5)' }, inplace=True) # ---------- Preview table ---------- add_heading("معاينة البيانات", level=2) add_table(df.head(10), title="أول 10 صفوف (RTL)") add_note("""يوضح الجدول عيّنة من الطلبات بين 2022-2025. نلاحظ تكرار أيام نهاية الأسبوع (الجمعة/السبت) في 6/10 صفوف تقريبًا، ما قد يشير إلى ارتفاع النشاط في نهاية الأسبوع. العلاقة بين مدة التوصيل والتقييم تبدو منطقية في بعض الصفوف: أقصر مدد (5-8 دقائق في طلبي أبها وبريدة) اقترنت بتقييمات مرتفعة (5/5). لكن توجد حالات تقييم منخفض رغم مدد متوسطة (تقييم 2 عند 8-10 دقائق)، ما يعني أن عوامل أخرى (جودة الطعام/الدقة/التواصل) تؤثر أيضًا. القيم المالية متفاوتة بشدة (مثال: 57.05 ريال مقابل 791.81 ريال). قد تكون هناك طلبات متعددة العناصر/مميزة ترفع الفاتورة؛ من المفيد تحليل توزيع الفواتير واكتشاف القيم الشاذة. ما الذي نستنتجه؟ نشاط ملحوظ قرب نهاية الأسبوع، واحتمال ارتباط إيجابي بين السرعة والرضا، لكن ليس حصريًا. ينبغي نمذجة التقييم بعوامل إضافية (نوع المطعم، المدينة، وقت الطلب، قيمة الفاتورة). وجود فواتير مرتفعة نسبيًا يستدعي فحص سياسات التوصيل/العروض لمعرفة أثرها على الرضا.""") from tabulate import tabulate import pandas as pd df.rename(columns={ 'Order Number': 'رقم الطلب', 'Order_City': 'المدينة', 'Restaurant Type': 'نوع المطعم', 'Day' : 'اليوم', 'Hour' : 'الساعة', 'Date': 'التاريخ', 'Time': 'الوقت', 'Total Bill (in Saudi Riyals)': 'قيمة الفاتورة (ريال)', 'Delivery Duration (in minutes)': 'مدة التوصيل (دقيقة)', 'Customer Rating (from 1 to 5 stars)': 'تقييم العميل (1-5)' }, inplace=True) df.head().style.set_table_styles( [{'selector': 'th', 'props': [('background-color', '#7E57C2'), ('color', 'white'), ('font-weight', 'bold')]}] ).set_caption("Table Example - Argami Style") desc = df.describe().style.set_table_styles( [{'selector': 'th', 'props': [('background-color', '#7E57C2'), ('color', 'white'), ('font-weight', 'bold')]}] ).set_caption("📊 إحصاءات وصفية للأعمدة العددية") desc # حساب القيم الفريدة في كل عمود unique_vals = df.nunique().reset_index() unique_vals.columns = ["العمود", "عدد القيم الفريدة"] unique_vals.style.set_table_styles( [{'selector': 'th', 'props': [('background-color', '#7E57C2'), ('color', 'white'), ('font-weight', 'bold')]}] ).set_caption("🔢 عدد القيم الفريدة لكل عمود") # Pie: Restaurant Type (Arabic labels) arabic_map = { "American":"أمريكي","Asian":"آسيوي","Italian":"إيطالي", "Desserts & Bakery":"حلويات ومخبوزات","Seafood":"مأكولات بحرية", "Coffee":"قهوة","Vegetarian/Vegan":"نباتي/فيغان", "Fast Food":"وجبات سريعة","Barbecue":"مشاوي","Bakeries":"مخابز", "Sweets":"حلويات","Indian Cuisine":"هندي","Sushi":"سوشي", "Pizzeria":"بيتزا","Italian Cuisine":"مطبخ إيطالي", } _map_lower = {k.lower(): v for k,v in arabic_map.items()} src = df["نوع المطعم"].astype(str) df["نوع المطعم (عربي)"] = src.str.strip().str.lower().map(_map_lower).fillna(src) orders_by_type = df["نوع المطعم (عربي)"].value_counts() plt.figure(figsize=(6,6)) plt.pie(orders_by_type.values, labels=[ar(x) for x in orders_by_type.index], autopct='%1.1f%%', startangle=140) plt.title(ar("الطلبات حسب نوع المطعم")) plt.tight_layout() # ---------- Plot 1: Histogram ---------- sns.set_theme(style='whitegrid') plt.figure(figsize=(8,4)) sns.histplot(df['مدة التوصيل (دقيقة)'], bins=15, kde=True) plt.title(ar('توزيع مدة التوصيل')); plt.xlabel(ar('مدة التوصيل (دقيقة)')); plt.ylabel(ar('العدد')) plt.tight_layout() add_figure(caption="توزيع مدة التوصيل", interpretation="يُظهر الرسم مدى انتشار أزمنة التوصيل. قمة الهرم تعني الفترات الأكثر شيوعًا. " "الذيل الطويل على اليمين (إن وُجد) يشير إلى طلبات استغرقت وقتًا أطول من المعتاد.") # ---------- Plot 2: Countplot (restaurant types) ---------- arabic_map = {"American":"أمريكي","Asian":"آسيوي","Italian":"إيطالي","Desserts & Bakery":"حلويات ومخبوزات", "Seafood":"مأكولات بحرية","Coffee":"قهوة","Vegetarian/Vegan":"نباتي/فيغان","Fast Food":"وجبات سريعة", "Barbecue":"مشاوي","Bakeries":"مخابز","Sweets":"حلويات","Indian Cuisine":"هندي", "Sushi":"سوشي","Pizzeria":"بيتزا","Italian Cuisine":"مطبخ إيطالي"} _map_lower = {k.lower(): v for k,v in arabic_map.items()} src = df.get("نوع المطعم") if "نوع المطعم" in df.columns else df.get("Restaurant Type") if src is not None: src = src.astype(str) df["نوع المطعم (عربي)"] = src.str.strip().str.lower().map(_map_lower).fillna(src) if "نوع المطعم (عربي)" in df.columns: order_ar = df["نوع المطعم (عربي)"].value_counts().index.tolist() plt.figure(figsize=(8,5)) ax = sns.countplot(data=df, y="نوع المطعم (عربي)", order=order_ar, color="#7E57C2") ax.set_title(ar("عدد الطلبات حسب نوع المطعم")); ax.set_xlabel(ar("عدد الطلبات")) ax.set_yticks(range(len(order_ar))); ax.set_yticklabels([ar(x) for x in order_ar]) plt.tight_layout() add_figure(caption="عدد الطلبات حسب نوع المطعم", interpretation="يوضح أي أنواع المطاعم تستحوذ على الطلبات. الفئات الأعلى تمثل تفضيلات العملاء " "أو تغطية أفضل للتوصيل. قارن النتائج مع المدن/المناطق عند الحاجة.") # ---------- Plot 3: Boxplot (time vs rating) ---------- plt.figure(figsize=(8,4)) sns.boxplot(x="تقييم العميل (1-5)", y="مدة التوصيل (دقيقة)", data=df) plt.title(ar("مدة التوصيل مقابل التقييم")) plt.xlabel(ar("تقييم العميل (١–٥)")); plt.ylabel(ar("مدة التوصيل (دقيقة)")) plt.tight_layout() add_figure(caption="مدة التوصيل مقابل التقييم", interpretation="إن كانت الصناديق عند التقييمات الأعلى أقل اتساعًا وأقصر وسطيًا، فقد يدل ذلك على " "ارتباط بين سرعة التوصيل ورضا العملاء. تحقق من القِيَم المتطرفة عند التقييمات المنخفضة.") # ---------- Optional: summary / next steps ---------- add_heading("خلاصة وخطوات تالية", level=2) add_list([ "تحسين تغطية/سعة التوصيل في الفترات/المدن ذات الذيل الطويل.", "توسيع الشراكات مع أنماط المطاعم الأعلى طلبًا.", "تحليل زمني أدق (حسب الساعة/اليوم) وربطه بموارد الأسطول." ])
يستعرض هذا التقرير بيانات توصيل الطعام في المملكة العربية السعودية بصورة شاملة، حيث يسلّط الضوء على حجم الطلبات، وتوزّعها الجغرافي بين المدن، والأنماط الزمنية الأكثر شيوعًا خلال أيام الأسبوع وأوقات الذروة. كما يتناول التقرير مقارنة بين أنواع المطاعم (مثل القهوة، البيتزا، المأكولات البحرية، والحلويات) وتحليل تفضيلات المستهلكين، إضافةً إلى قياس مستوى رضا العملاء استنادًا إلى تقييماتهم. وقد تم إعداد المخططات التوضيحية والجداول بالعربية، مع تفسير تفصيلي تحت كل جزء لزيادة الفهم وربط الأرقام بالواقع. ويأتي هذا العمل ثمرة تعاون بين منصة أرقامي وفريق PrepX، في خطوة تهدف إلى تعزيز الوعي بالبيانات ودعم صناع القرار ورواد الأعمال في قطاع خدمات التوصيل بالمملكة.
رقم الطلب | التاريخ | اليوم | الوقت | الساعة | المدينة | نوع المطعم | قيمة الفاتورة (ريال) | مدة التوصيل (دقيقة) | تقييم العميل (1-5) |
---|---|---|---|---|---|---|---|---|---|
203 | 2025-01-18 00:00:00 | Saturday | 12:17:00 | 12 | Jeddah | Desserts & Bakery | 252.730000 | 15 | 3 |
204 | 2023-05-12 00:00:00 | Friday | 07:40:00 | 7 | Buraidah | American | 535.700000 | 7 | 4 |
205 | 2023-05-10 00:00:00 | Wednesday | 07:47:00 | 7 | Hail | Coffee | 395.110000 | 14 | 4 |
206 | 2023-04-03 00:00:00 | Monday | 11:39:00 | 11 | Abha | American | 698.110000 | 5 | 5 |
207 | 2024-12-21 00:00:00 | Saturday | 01:30:00 | 1 | Buraidah | Coffee | 499.870000 | 8 | 5 |
208 | 2023-10-21 00:00:00 | Saturday | 07:49:00 | 7 | Jeddah | Asian | 369.380000 | 19 | 3 |
209 | 2022-02-18 00:00:00 | Friday | 06:55:00 | 6 | Dammam | Asian | 57.050000 | 9 | 3 |
210 | 2023-05-26 00:00:00 | Friday | 01:57:00 | 1 | Abha | Asian | 791.810000 | 10 | 2 |
211 | 2023-09-17 00:00:00 | Sunday | 06:31:00 | 6 | Buraidah | Vegetarian/Vegan | 233.820000 | 8 | 2 |
212 | 2022-02-10 00:00:00 | Thursday | 03:54:00 | 3 | Tabuk | Asian | 243.050000 | 12 | 4 |