{"id":"l-pda-2-2","courseId":"python-data-analysis","lang":"ar","kind":"lesson","summary":"حمّل ملف CSV إلى DataFrame باستخدام read_csv، وطبّق روتين فحص من خمس خطوات (shape و head و info و describe و value_counts) يلتقط المشكلات قبل أن تصل إلى أرقامك.","html":"<p>يرسل لك رئيس النمو الملف <code dir=\"ltr\">orders.csv</code> ويطلب “رقم إيراد سريعًا”. أسرع طريقة لتقديم إجابة خاطئة هي أن تحمّل الملف وتجمع عمودًا مباشرة. كل محلل خبير يفعل الشيء نفسه أولًا: ينظر إلى البيانات. لا ينظر إليها كلها، بل يجري بضعة فحوص مقصودة تستغرق ثلاثين ثانية وتلتقط معظم المشكلات قبل أن تصل إلى شريحة عرض.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">الخطوة 1: حمّل الملف، ثم افحص shape و head()</h2>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"0\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">orders </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.read_csv(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"orders.csv\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(orders.shape)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(orders.head().to_string())</span></span></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<p>تقرأ <code dir=\"ltr\">read_csv</code> صف العناوين على أنه أسماء الأعمدة، وتخمّن نوع كل عمود، وتعيد DataFrame. تعرض <code dir=\"ltr\">head()</code> أول خمسة صفوف (<code dir=\"ltr\">head(10)</code> تعرض عشرة، و<code dir=\"ltr\">tail()</code> تعرض الأخيرة، و<code dir=\"ltr\">sample(5)</code> تعرض خمسة عشوائيًا، وهي أفضل في كشف الغرائب من الصفوف الأولى). أما <code dir=\"ltr\">.to_string()</code> فتطبع كل الأعمدة بدلًا من إخفاء الوسطى منها خلف <code dir=\"ltr\">...</code>.</p>\n<p>2,066 صفًا و7 أعمدة. قبل أن تكمل، قل بصوت عالٍ ما تتوقّعه: صف لكل طلب، ومعرّف الطلب، والعميل، والتاريخ، والحالة، والقناة، وكوبون اختياري، ورسوم الشحن. الفحوص التالية تؤكّد كل توقّع أو تنفيه.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">الخطوة 2: تعرض info() الأنواع والخانات الفارغة</h2>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"1\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">orders </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.read_csv(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"orders.csv\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">orders.info()</span></span></code></pre><div class=\"run-output\" data-run-output=\"1\" hidden></div></div>\n<p>تطبع <code dir=\"ltr\">info()</code> بنفسها، دون حاجة إلى <code dir=\"ltr\">print()</code>. اقرأها عمودًا عمودًا. يخبرك <code dir=\"ltr\">Non-Null Count</code> بعدد الصفوف التي فيها قيمة: للعمود <code dir=\"ltr\">coupon_code</code> قيم في 388 صفًا من 2,066، فمعظم الطلبات لم تستخدم كوبونًا. ويخبرك <code dir=\"ltr\">Dtype</code> بما فهمته pandas من كل عمود: المعرّفات <code dir=\"ltr\">int64</code>، والرسوم <code dir=\"ltr\">float64</code>، وكل ما عدا ذلك <code dir=\"ltr\">object</code>، أي نص.</p>\n<p>وهذا يشمل <code dir=\"ltr\">order_date</code>. حين تُخزَّن التواريخ كنصوص، فإنها لا تُرتَّب ترتيبًا صحيحًا إلا لأن هذا الملف يكتبها بالسنة أولًا مصادفةً، ولا تستطيع الإجابة عن سؤال “أيّ شهر؟”. اطلب من <code dir=\"ltr\">read_csv</code> أن تحلّلها أثناء التحميل:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"2\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">orders </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.read_csv(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"orders.csv\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">parse_dates</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"order_date\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(orders.dtypes)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(orders[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"order_date\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].min(), </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"to\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, orders[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"order_date\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].max())</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<p>الآن أصبح العمود <code dir=\"ltr\">datetime64[ns]</code>، وتؤكّد <code dir=\"ltr\">min()</code> و<code dir=\"ltr\">max()</code> أن البيانات تمتد من 2 يناير 2024 إلى 30 ديسمبر 2025. فحص النطاق الزمني لكل ملف جديد عادة تستحق أن تكتسبها: شهر مفقود أو تاريخ شارد في 1970 يظهران فورًا.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">الخطوة 3: تلخّص describe() الأرقام</h2>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"3\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">orders </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.read_csv(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"orders.csv\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(orders.describe().round(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))</span></span></code></pre><div class=\"run-output\" data-run-output=\"3\" hidden></div></div>\n<p>تعطيك <code dir=\"ltr\">describe()</code> العدد والمتوسط والانحراف المعياري والحد الأدنى والأرباع (quartiles) والحد الأقصى لكل عمود رقمي. رسوم الشحن تتراوح بين 0 و9.99 بوسيط 4.99: أرقام معقولة. لكنها أيضًا تعرض بأمانة متوسطًا لـ <code dir=\"ltr\">customer_id</code> قدره 300.47، وهذا لا يعني شيئًا. المعرّفات تسميات تصادف أنها أرقام. اقرأ <code dir=\"ltr\">describe()</code> فقط للأعمدة التي يكون للحساب فيها معنى، واستخدمها لتلتقط القيم المستحيلة: كميات سالبة، أو أسعار صفرية، أو حد أقصى يساوي مئة ضعف الوسيط.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">الخطوة 4: value_counts() على الأعمدة النصية</h2>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"4\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">orders </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.read_csv(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"orders.csv\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(orders[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"status\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].value_counts())</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(orders[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"coupon_code\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].value_counts(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">dropna</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">False</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(orders[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"channel\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].value_counts(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">normalize</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">True</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">).round(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))</span></span></code></pre><div class=\"run-output\" data-run-output=\"4\" hidden></div></div>\n<p>تسرد <code dir=\"ltr\">value_counts()</code> كل قيمة مختلفة مع عدد مرات ظهورها، الأكثر شيوعًا أولًا. بها تجد الأخطاء الكتابية (<code dir=\"ltr\">&quot;Web&quot;</code> بجانب <code dir=\"ltr\">&quot;web&quot;</code>)، والفئات غير المتوقّعة، وحجم كل مجموعة. يُدرج <code dir=\"ltr\">dropna=False</code> القيم المفقودة كصف مستقل، ويعطيك <code dir=\"ltr\">normalize=True</code> الحصص بدلًا من الأعداد: 55% من الطلبات جاءت عبر الويب.</p>\n<p>لاحظ أن 105 طلبات أُلغيت. هل يجب أن يشملها الإيراد؟ هذا قرار عمل لا قرار برمجي، وستتخذه صراحةً في القسم 4. والفحص هو المكان الذي تظهر فيه هذه القرارات لأول مرة.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">الخطوة 5: تحقّق مما توشك أن تفترضه</h2>\n<p>أخيرًا، حوّل توقّعاتك إلى فحوص من سطر واحد:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"5\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"5\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">orders </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.read_csv(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"orders.csv\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">customers </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.read_csv(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"customers.csv\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(orders[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"order_id\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].is_unique)            </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># one row per order?</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(orders[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"customer_id\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].nunique(), </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"customers ordered\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">len</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(customers), </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"customers in total\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(customers[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"referred_by\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].dtype)</span></span></code></pre><div class=\"run-output\" data-run-output=\"5\" hidden></div></div>\n<p>معرّف الطلب فريد، فالصف الواحد هو فعلًا طلب واحد. 515 عميلًا من 600 طلبوا مرة واحدة على الأقل؛ والـ 85 الآخرون سجّلوا ولم يشتروا أبدًا، وهذا مهم لاحقًا حين تحسب “الإيراد لكل عميل”. وقد حُمّل <code dir=\"ltr\">referred_by</code> على هيئة <code dir=\"ltr\">float64</code> مع أنه يحمل معرّفات عملاء: معظم العملاء لم يُحالوا من أحد، فأصبحت الخانات الفارغة <code dir=\"ltr\">NaN</code>، و<code dir=\"ltr\">NaN</code> في pandas الكلاسيكية عدد عشري، فصار العمود كله عشريًا.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>الثقة بأول خمسة صفوف</span></p>\n<p>تعرض <code dir=\"ltr\">head()</code> أكثر أجزاء الملفات ترتيبًا في كثير من الأحيان، لأن الملفات المُصدَّرة تكون عادةً مرتّبة بحسب التاريخ أو المعرّف. أما المشكلات مثل الخانات الفارغة والكتابات الغريبة والقيم الشاذة فتميل إلى أن تكون في الأسفل. أتبِع <code dir=\"ltr\">head()</code> دائمًا بـ <code dir=\"ltr\">info()</code> و<code dir=\"ltr\">value_counts()</code>، اللتين تنظران إلى كل الصفوف.</p>\n</aside>\n<aside class=\"callout callout-why\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><circle cx=\"12\" cy=\"12\" r=\"6\"/><circle cx=\"12\" cy=\"12\" r=\"2\"/></svg><span><span class=\"callout-kind\">لماذا يهمّ هذا</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>لماذا يهم هذا</span></p>\n<p>الفحص ليس عملًا شكليًا. كل اكتشاف هنا (الكوبونات مفقودة في الأغلب، والطلبات الملغاة موجودة، والمعرّفات مخزّنة كأعداد عشرية، و85 عميلًا بلا طلبات) يغيّر طريقة كتابة حساب لاحق. اكتشافها الآن يكلّف ثلاثين ثانية؛ واكتشافها بعد عرض رقم يكلّفك مصداقيتك.</p>\n</aside>\n<p>في التمرين تطبّق الروتين على <code dir=\"ltr\">customers.csv</code>. وفي الدرس التالي تتعلّم استخراج الصفوف والأعمدة التي تحتاجها بالضبط باستخدام <code dir=\"ltr\">.loc</code> و<code dir=\"ltr\">.iloc</code>.</p>\n","toc":[{"id":"sec-1","text":"الخطوة 1: حمّل الملف، ثم افحص shape و head()","level":2},{"id":"sec-2","text":"الخطوة 2: تعرض info() الأنواع والخانات الفارغة","level":2},{"id":"sec-3","text":"الخطوة 3: تلخّص describe() الأرقام","level":2},{"id":"sec-4","text":"الخطوة 4: value_counts() على الأعمدة النصية","level":2},{"id":"sec-5","text":"الخطوة 5: تحقّق مما توشك أن تفترضه","level":2}],"takeaways":["<code dir=\"ltr\">pd.read_csv(&quot;file.csv&quot;)</code> تحمّل جدولًا؛ و<code dir=\"ltr\">parse_dates=[...]</code> تحوّل أعمدة التواريخ إلى تواريخ حقيقية أثناء التحميل.","طبّق الروتين نفسه على كل ملف جديد - <code dir=\"ltr\">shape</code> ثم <code dir=\"ltr\">head()</code> ثم <code dir=\"ltr\">info()</code> ثم <code dir=\"ltr\">describe()</code>، ثم <code dir=\"ltr\">value_counts()</code> على الأعمدة النصية.","تعرض <code dir=\"ltr\">info()</code> نوع كل عمود (dtype) وعدد قيمه غير الفارغة، فتكشف القيم المفقودة والأرقام المخزّنة كنصوص.","العمود الصحيح الذي فيه خانات فارغة يُحمَّل على هيئة <code dir=\"ltr\">float64</code>، لأن <code dir=\"ltr\">NaN</code> الكلاسيكية عدد عشري.","تحقّق بالكود من الحقائق التي ستعتمد عليها، مثل أن المعرّف فريد، بسطر مثل <code dir=\"ltr\">orders[&quot;order_id&quot;].is_unique</code>."],"further":[{"title":"pandas.read_csv","url":"https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html"},{"title":"pandas.DataFrame.info","url":"https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.info.html"},{"title":"pandas.Series.value_counts","url":"https://pandas.pydata.org/docs/reference/api/pandas.Series.value_counts.html"}],"quiz":[{"q":"<p>تعرض <code dir=\"ltr\">info()</code> السطر <code dir=\"ltr\">coupon_code  388 non-null  object</code> لجدول فيه 2,066 صفًا. ماذا يخبرك ذلك؟</p>","options":[{"text":"في العمود 388 كود كوبون مختلفًا.","why":"عدد القيم غير الفارغة يتعلّق بالقيم المفقودة، لا بالقيم المختلفة. الدالة <code dir=\"ltr\">nunique()</code> هي التي تعدّ القيم المختلفة."},{"text":"فشل تحميل 388 صفًا فحُذفت.","why":"تحتفظ <code dir=\"ltr\">read_csv</code> بكل الصفوف؛ الصفوف الـ 1,678 الأخرى موجودة لكن الكوبون فيها مفقود."},{"text":"1,678 طلبًا بلا كود كوبون، والبقية تحمل نصًا.","why":"صحيح. 2,066 ناقص 388 قيم مفقودة، و<code dir=\"ltr\">object</code> تعني أن القيم المخزّنة نصوص (أو خليط)."},{"text":"يجب تحويل العمود إلى أرقام.","why":"أكواد الكوبونات مثل <code dir=\"ltr\">WELCOME10</code> تسميات؛ و<code dir=\"ltr\">object</code> هو النوع المناسب لها في pandas 2."}],"answer":2},{"q":"<p>تعرض <code dir=\"ltr\">describe()</code> القيمة <code dir=\"ltr\">mean 300.47</code> للعمود <code dir=\"ltr\">customer_id</code>. كيف تقرأ ذلك؟</p>","options":[{"text":"العميل المتوسط قدّم نحو 300 طلب.","why":"لا شيء هنا يعدّ الطلبات لكل عميل؛ هذا حساب على أرقام المعرّفات."},{"text":"لا معنى له؛ المعرّفات تسميات تصادف أنها أرقام، فمتوسطها لا يقول شيئًا.","why":"صحيح. تلخّص <code dir=\"ltr\">describe()</code> كل عمود رقمي، ومنها المعرّفات. اقرأها فقط للأعمدة التي يكون للحساب فيها معنى."},{"text":"العميل رقم 300 هو العميل النموذجي.","why":"متوسط التسميات لا يحدّد أي شيء نموذجي. ستحتاج سؤالًا مختلفًا وحسابًا مختلفًا."}],"answer":1},{"q":"<p>في <code dir=\"ltr\">customers.csv</code> يحمل العمود <code dir=\"ltr\">referred_by</code> معرّفات عملاء، لكنه يُحمَّل على هيئة <code dir=\"ltr\">float64</code>. لماذا؟</p>","options":[{"text":"بعض المعرّفات في الملف مكتوبة بكسور عشرية.","why":"الملف لا يحتوي إلا أعدادًا صحيحة. تغيّر النوع سببه الخانات الفارغة."},{"text":"تحمّل <code dir=\"ltr\">read_csv</code> أعمدة المعرّفات دائمًا كأعداد عشرية.","why":"العمود <code dir=\"ltr\">customer_id</code> في الملف نفسه يُحمَّل على هيئة <code dir=\"ltr\">int64</code>. الفرق هو القيم المفقودة."},{"text":"في العمود خانات فارغة تُحمَّل على هيئة <code dir=\"ltr\">NaN</code>، و<code dir=\"ltr\">NaN</code> الكلاسيكية لا توجد إلا في الأعمدة العشرية.","why":"صحيح. 503 عملاء لم يُحالوا من أحد، فتستخدم pandas النوع <code dir=\"ltr\">float64</code> لتحمل <code dir=\"ltr\">NaN</code>. ويعرض الدرس 3.1 النوع <code dir=\"ltr\">Int64</code> القابل للقيم المفقودة الذي يتجنّب ذلك."}],"answer":2}],"exercise":{"kind":"python","files":["customers.csv"],"starter":"import pandas as pd\n\n# Load customers.csv with signup_date parsed as a date\ncustomers = None\n\nn_rows = None             # number of customers (rows)\nn_countries = None        # how many distinct countries\ntop_country = None        # the country with the most customers\nmissing_referrals = None  # how many rows have no referred_by value\nfirst_signup = None       # the earliest signup_date\n","solution":"import pandas as pd\n\ncustomers = pd.read_csv(\"customers.csv\", parse_dates=[\"signup_date\"])\ncustomers.info()\n\nn_rows = len(customers)\nn_countries = customers[\"country\"].nunique()\ntop_country = customers[\"country\"].value_counts().idxmax()\nmissing_referrals = customers[\"referred_by\"].isna().sum()\nfirst_signup = customers[\"signup_date\"].min()\n","checks":[{"id":"loaded","test":"isinstance(customers, pd.DataFrame) and customers.shape == (600, 9)"},{"id":"dates-parsed","test":"pd.api.types.is_datetime64_any_dtype(customers['signup_date'])"},{"id":"counts","test":"n_rows == 600 and n_countries == 8"},{"id":"top-country","test":"top_country == 'United States'"},{"id":"missing","test":"int(missing_referrals) == 503"},{"id":"first-signup","test":"str(pd.Timestamp(first_signup).date()) == '2024-01-01'"}],"title":"افحص جدول العملاء","prompt":"<p>حمّل <code dir=\"ltr\">customers.csv</code> إلى <code dir=\"ltr\">customers</code>، مع تحليل <code dir=\"ltr\">signup_date</code> كتاريخ أثناء التحميل. ثم أجب عن خمسة أسئلة بالكود: <code dir=\"ltr\">n_rows</code> (عدد الصفوف)، و<code dir=\"ltr\">n_countries</code> (عدد الدول المختلفة)، و<code dir=\"ltr\">top_country</code> (الدولة التي فيها أكبر عدد من العملاء)، و<code dir=\"ltr\">missing_referrals</code> (عدد الصفوف التي ليس فيها <code dir=\"ltr\">referred_by</code>)، و<code dir=\"ltr\">first_signup</code> (أقدم تاريخ تسجيل).</p>\n","hints":["<code dir=\"ltr\">pd.read_csv(&quot;customers.csv&quot;, parse_dates=[&quot;signup_date&quot;])</code> تحمّل وتحوّل في خطوة واحدة.","<code dir=\"ltr\">nunique()</code> تعدّ القيم المختلفة؛ و<code dir=\"ltr\">value_counts()</code> ترتّب بحسب العدد، فتكون أول تسمية فيها هي الأكثر شيوعًا.","<code dir=\"ltr\">customers[&quot;referred_by&quot;].isna().sum()</code> تعدّ الخانات الفارغة: <code dir=\"ltr\">True</code> تُحسب 1. و<code dir=\"ltr\">customers[&quot;signup_date&quot;].min()</code> تعطي أقدم تاريخ."],"explanation":"<p>تعدّ <code dir=\"ltr\">len(df)</code> الصفوف، وتؤكّد <code dir=\"ltr\">nunique()</code> أن Cartwheel تبيع لثماني دول بالضبط، فلا توجد كتابات مختلفة مختبئة في هذا الجدول النظيف (أما الملف الفوضوي فقصة أخرى). وتعيد <code dir=\"ltr\">value_counts().idxmax()</code> التسمية صاحبة أعلى عدد: الولايات المتحدة، بـ 104 عملاء. جمع Series منطقية يعدّ قيم <code dir=\"ltr\">True</code> فيها، وهذه الطريقة المعتادة لعدّ الخانات الفارغة. ولأن <code dir=\"ltr\">signup_date</code> حُلّل كتاريخ، تقارن <code dir=\"ltr\">min()</code> تواريخ حقيقية لا نصوصًا، وتعيد <code dir=\"ltr\">Timestamp</code>، وهو نوع التاريخ والوقت في pandas.</p>\n","checkLabels":{"loaded":"في <code dir=\"ltr\">customers</code> 600 صف و9 أعمدة","dates-parsed":"<code dir=\"ltr\">signup_date</code> عمود من نوع datetime","counts":"600 صف و8 دول","top-country":"الدولة الأولى هي الولايات المتحدة","missing":"503 عملاء ليست لديهم إحالة","first-signup":"أول تسجيل كان في 2024-01-01"}},"words":641,"readMinutes":4}