سرنخ — خودآموز برنامه‌نویسی برای هوش مصنوعی (مقدماتی)

فصل ۴ از ۱۰

پیشرفت ترم
۰٪

ترم ۲ · داده: دیدن، تمیز کردن، فهمیدن

انتخاب، فیلتر، ستونِ تازه

فصل ۴پیش‌نمایش رایگان

در این فصل چه یاد می‌گیری#

جدول را خواندی و می‌دانی داخلش چیست. حالا باید بتوانی از آن چیزی بیرون بکشی: یک ستونِ خاص، ردیف‌هایی که شرطی دارند، مرتب‌شده بر اساسِ چیزی که برایت مهم است. در این فصل سه ابزارِ انتخاب را یاد می‌گیری، ماسکِ شرطیِ فصلِ ۲ را روی یک جدولِ واقعی به‌کار می‌بری، و ستونِ محاسبه‌شدهٔ خودت را می‌سازی. این‌ها را در هر پروژهٔ داده‌ای که تا آخرِ عمر بنویسی، روزی ده بار به‌کار می‌بری.

یک ورقهٔ شفاف با پنجره‌های بریده که روی یک جدول گذاشته شده و فقط بعضی ردیف‌ها از آن دیده می‌شوند

آخر این فصل می‌توانی:

  • با loc و iloc به هر ردیف و ستونی که بخواهی برسی و تفاوتشان را بگویی
  • با ماسکِ شرطی ردیف‌ها را فیلتر کنی و چند شرط را ترکیب کنی
  • جدول را بر اساسِ یک ستون مرتب کنی
  • ستونِ محاسبه‌شدهٔ تازه بسازی

قبل از شروع#

از فصل ۲: ماسکِ شرطی، و اینکه ترکیبِ شرط‌ها با & و | نوشته می‌شود نه and و or.

از فصل ۳: df["col"] یک Series می‌دهد و df[["a", "b"]] یک DataFrame.

سلولِ راه‌اندازی: همان laptops.csv فصلِ قبل. سلولِ بالای نوت‌بوک دوباره می‌سازدش.

📓 نوت‌بوک: نوت‌بوک این فصل را در Colab باز کن — همهٔ کدهای این فصل آماده و به‌ترتیب داخلش هست.

۱. loc و iloc: دو راهِ متفاوتِ اشاره‌کردن#

import pandas as pd

df = pd.read_csv("laptops.csv")

print(df.loc[0, "brand"])
print(df.iloc[0, 0])
print(df.loc[2:4, ["brand", "year"]])
اپل
اپل
   brand  year
2    اپل  2024
3  ایسوس  2023
4   لنوو  2019

هر دو خطِ اول یک چیز دادند، ولی از دو راهِ کاملاً متفاوت:

  • loc با برچسب کار می‌کند: برچسبِ ردیف (اندیس) و نامِ ستون.
  • iloc با شمارهٔ جایگاه کار می‌کند: ردیفِ چندم، ستونِ چندم — دقیقاً مثلِ آرایهٔ numpy.

اینجا هر دو یک جواب دادند فقط به این دلیل که اندیسِ ما اعدادِ ۰ تا ۲۴۳ است. به‌محضِ اینکه فیلتر کنی یا مرتب کنی، اندیس دیگر با جایگاه یکی نیست و این دو از هم جدا می‌شوند.

⚠️ مواظب باش: یک تفاوتِ ظریف که یک بار همه را می‌گیرد: df.loc[2:4] سه ردیف داد — ۲ و ۳ و ۴. برخلافِ برشِ پایتون و برخلافِ iloc، loc انتهای بازه را شامل می‌شود، چون با برچسب کار می‌کند نه با جایگاه. df.iloc[2:4] فقط دو ردیف می‌دهد.

قبل از ادامه، جواب بده: جدولی را بر اساسِ قیمت مرتب کرده‌ای و ردیفِ اولِ نتیجه اندیسِ ۱۹۷ دارد. برای گرفتنِ آن ردیف، df.loc[0] را به‌کار ببری یا df.iloc[0]؟ جواب: iloc[0]. loc[0] سراغِ ردیفی می‌رود که برچسبش صفر است، که حالا جای دیگری در جدول است. این تفاوت بعد از هر مرتب‌سازی و هر فیلتری اهمیت پیدا می‌کند.

۲. فیلتر: همان ماسکِ فصلِ ۲#

recent = df[df["year"] >= 2023]

print(recent.shape)
print(recent["brand"].value_counts().head(3))
(55, 5)
brand
ایسوس    18
لنوو     14
اچ پی     8
Name: count, dtype: int64

df["year"] >= 2023 یک Series از True/False می‌دهد — همان ماسک. گذاشتنش داخلِ کروشهٔ df یعنی «فقط ردیف‌هایی که True شدند».

از ۲۴۴ ردیف، ۵۵ تا ماندند. عادت کن بعد از هر فیلتر shape را چاپ کنی: اگر عددی که می‌گیری خیلی بزرگ‌تر یا کوچک‌تر از انتظارت است، شرطت همانی نیست که فکر می‌کردی.

ترکیبِ شرط‌ها دقیقاً مثلِ numpy است:

selected = df[(df["year"] >= 2022) & (df["ram_gb"] >= 16)]
print(selected.shape)
(29, 5)

چک کن: ۲۹ ردیف. اگر عددِ خیلی بزرگ‌تری گرفتی، احتمالاً پرانتزها را جا انداخته‌ای. اگر خطا گرفتی، بخشِ ۵ همین فصل را ببین.

۳. مرتب‌سازی#

newest = df.sort_values("year", ascending=False)
print(newest.head(3)[["brand", "year"]])
   brand  year
7   لنوو  2205
2    اپل  2024
39  لنوو  2024

sort_values جدولِ مرتب‌شده را برمی‌گرداند و اصل را دست‌نخورده می‌گذارد — پس باید نتیجه را در متغیری بگیری، وگرنه کاری نکرده‌ای.

به اندیس‌ها نگاه کن: 7، 2، 39. ردیف‌ها جابه‌جا شدند ولی برچسبشان با خودشان آمد. این دقیقاً همان چیزی است که بخشِ ۱ دربارهٔ loc و iloc می‌گفت.

و به ردیفِ اول نگاه کن: سالِ ۲۲۰۵. همان مقدارِ غیرممکنی که در فصلِ ۳ در describe() دیدیم، حالا در صدرِ فهرستِ «جدیدترین‌ها» نشسته است.

📏 اندازه بگیر: این یک درسِ کوچک ولی مهم است: مرتب‌سازی، مقدارهای خراب را به بالای فهرست می‌آورد. پس هر بار که چیزی را مرتب کردی، اولین و آخرین چند ردیف را نگاه کن — نه برای نتیجه‌گیری، بلکه برای پیدا کردنِ خرابی. این ارزان‌ترین بازرسیِ داده است که می‌شناسیم.

۴. ستونِ تازه#

df["ram_mb"] = df["ram_gb"] * 1024
df["is_recent"] = df["year"] >= 2022

print(df[["ram_gb", "ram_mb", "is_recent"]].head(3))
print(df["is_recent"].mean().round(3))
   ram_gb   ram_mb  is_recent
0    32.0  32768.0      False
1    16.0  16384.0      False
2     8.0   8192.0       True
0.311

ساختنِ ستونِ تازه دقیقاً مثلِ گذاشتنِ کلیدِ تازه در یک dict است: df["نام تازه"] = مقدار. و چون عملیات برداری است، یک خط کافی است — بدونِ حلقه، برای هر ۲۴۴ ردیف.

آن mean() روی ستونِ True/False همان ترفندِ فصلِ ۲ است: ۳۱٫۱ درصد از آگهی‌ها مربوط به سالِ ۲۰۲۲ به بعدند.

💡 نکته: به .round(3) دقت کن. بدونِ آن عددِ 0.3110655737704918 را می‌گرفتی — شانزده رقمِ اعشار برای یک درصد. عادت کن هر عددی که قرار است خوانده شود را گِرد کنی. این نه تزئین است و نه بی‌دقتی؛ نشان‌دادنِ دقتی که وجود ندارد، خودش یک نوع بی‌دقتی است.

۵. یک خطای واقعی: پرانتزهای جامانده#

df[df["year"] >= 2022 & df["ram_gb"] >= 16]
TypeError: Cannot perform 'rand_' with a dtyped [float64] array and scalar of type [bool]

پیام گیج‌کننده است چون از لایه‌های درونیِ pandas می‌آید، ولی علتش ساده است: عملگرِ & تقدمِ بالاتری از >= دارد، پس پایتون اول 2022 & df["ram_gb"] را حساب می‌کند — یعنی «و»ی منطقیِ یک عدد با یک ستونِ اعشاری، که بی‌معناست.

راهِ رفعش همان چیزی است که در بخشِ ۲ نوشتیم: هر شرط را داخلِ پرانتزِ خودش بگذار.

🔧 اگر کار نکرد: اگر به‌جای این، پیامِ ValueError: The truth value of a Series is ambiguous گرفتی، یعنی and نوشته‌ای به‌جای &. هر دو خطا یک ریشه دارند و یک راهِ حل: & و | و ~، هر کدام با پرانتزِ خودشان.

🤖 از دستیارت بپرس: «در pandas تفاوتِ loc و iloc چیست؟ یک مثال بزن که در آن نتیجه‌شان متفاوت باشد.» تأکید روی «متفاوت» عمدی است: مثالی که هر دو یک جواب می‌دهند چیزی یاد نمی‌دهد. جوابش را در نوت‌بوک اجرا کن و ببین واقعاً متفاوت شد یا نه.

واژه‌های تازهٔ این فصل#

کلمه تلفظ به حروف فارسی یعنی چه
loc لوک انتخاب با برچسب؛ انتهای بازه را شامل می‌شود
iloc آی‌لوک انتخاب با شمارهٔ جایگاه؛ مثلِ برشِ پایتون
sort_values سورت ولیوز جدولِ مرتب‌شده را برمی‌گرداند، اصل را عوض نمی‌کند

تمرین‌ها

اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.

در فصل بعد#

تا اینجا چهار مشکل در داده پیدا کرده‌ای و از کنارِ همه‌شان رد شده‌ای: قیمتِ متنی، خانه‌های خالی، سالِ غیرممکن، و برندی که به دو شکل نوشته شده. تمرینِ ستاره‌دار پنجمی را هم نشانت داد. فصلِ بعد یک فصلِ ⚠️ است و کاملاً به همین اختصاص دارد — دادهٔ کثیف — و آنجاست که کارِ واقعیِ علمِ داده شروع می‌شود. مهم‌تر از تکنیک‌ها، یک چیز را یاد می‌گیری: هر تصمیمِ پاک‌سازی، یک تصمیم دربارهٔ معنای داده است، نه یک کارِ فنی.

به آخر این فصل رسیدی!

اگر ساختی و جواب داد، این دکمه مال توست.