در این فصل چه یاد میگیری#
جدولِ تمیزت ۲۳۸ ردیف دارد. هیچکس نمیتواند ۲۳۸ ردیف را نگاه کند و بفهمد چه خبر است. کاری که میکنی این است: ردیفها را گروه میکنی و از هر گروه یک عدد میگیری — «میانگینِ قیمتِ هر برند»، «تعدادِ آگهی در هر شهر». در این فصل groupby را یاد میگیری، پرکاربردترین ابزارِ تحلیلِ داده، و همانجا میبینی چطور یک جدولِ ۲۳۸ ردیفی در سه خط به یک جدولِ پنجردیفیِ کاملاً گویا تبدیل میشود.

آخر این فصل میتوانی:
- با
groupbyداده را گروه کنی و از هر گروه یک عدد بگیری - با
aggچند آمار را همزمان بگیری - روی دو ستون همزمان گروهبندی کنی
- با
pivot_tableجدولِ دوبعدی بسازی - بگویی چرا
countهر گروه بهاندازهٔmeanآن مهم است
قبل از شروع#
از فصل ۵: جدولِ تمیز. سلولِ راهاندازی همان پنج قدمِ پاکسازی را تکرار میکند و فایلِ laptops_clean.csv را میسازد، تا لازم نباشد هر فصل از نو پاکسازی کنی.
از ترمِ ۱ فصل ۶: الگوی انباشتگر — groupby دقیقاً همان کار را میکند، فقط برای هر گروه جداگانه.
📓 نوتبوک: نوتبوک این فصل را در Colab باز کن — همهٔ کدهای این فصل آماده و بهترتیب داخلش هست.
۱. اولین گروهبندی#
import pandas as pd
df = pd.read_csv("laptops_clean.csv")
print(df.groupby("brand")["price"].mean().round(0))
brand
اپل 46025000.0
اچ پی 23540000.0
ایسوس 24893506.0
دل 22451111.0
لنوو 23745833.0
Name: price, dtype: float64
این خط را از چپ بخوان: «جدول را بر اساسِ brand گروه کن، از هر گروه ستونِ price را بردار، و میانگینش را بگیر».
۲۳۸ ردیف شد پنج عدد، و همان پنج عدد چیزی میگویند که هیچکس با نگاهکردن به ردیفها نمیفهمید: اپل تقریباً دو برابرِ بقیه است.
الگوی groupby همیشه سه تکه دارد و به آن تقسیم-اعمال-ترکیب میگویند: داده به گروهها تقسیم میشود، روی هر گروه یک تابع اعمال میشود، و نتیجهها در یک جدول ترکیب میشوند.
⚠️ مواظب باش: اگر فصلِ ۵ را انجام نداده بودی و روی دادهٔ خام گروهبندی میکردی، هفت گروه میگرفتی نه پنج — «ایسوس» و «ايسوس» جدا میشدند و میانگینِ هر دو غلط میشد. گروهبندی روی دادهٔ تمیزنشده، بدترین جایی است که کثیفیِ متن خودش را نشان میدهد، چون نتیجهاش کاملاً منطقی بهنظر میرسد.
۲. agg: چند آمار با هم#
یک عدد در هر گروه کافی نیست:
summary = df.groupby("brand")["price"].agg(["count", "mean", "median"]).round(0)
print(summary)
count mean median
brand
اپل 28 46025000.0 45050000.0
اچ پی 40 23540000.0 23750000.0
ایسوس 77 24893506.0 25100000.0
دل 45 22451111.0 22200000.0
لنوو 48 23745833.0 22100000.0
حالا تصویر کاملتر است. agg یک فهرست از نامِ تابعها میگیرد و برای هرکدام یک ستون میسازد.
📏 اندازه بگیر: ستونِ
countرا جدی بگیر — بهاندازهٔmeanمهم است و تقریباً همیشه جا میافتد. اپل فقط ۲۸ آگهی دارد در برابرِ ۷۷ آگهیِ ایسوس. یعنی میانگینِ اپل روی نمونهٔ کوچکتری حساب شده و بیثباتتر است: یک آگهیِ عجیب، میانگینِ ۲۸تایی را خیلی بیشتر تکان میدهد تا ۷۷تایی را. هر وقت میانگینِ یک گروه را گزارش کردی، تعدادش را هم گزارش کن. میانگینی که تعدادش را نمیدانی، عددی است که نمیدانی چقدر باید باورش کنی.
و به فاصلهٔ mean و median نگاه کن. برای «لنوو» میانگین ۲۳٫۷ میلیون است ولی میانه ۲۲٫۱ — یعنی چند آگهیِ گران، میانگین را بالا کشیدهاند. هر جا این دو از هم فاصله بگیرند، توزیع متقارن نیست.
🌱 ریشهاش کجاست: اینکه چرا میانگین با یک مقدارِ بزرگ جابهجا میشود ولی میانه تقریباً بیحرکت میماند، دقیقاً موضوعِ ریشه، ترم ۶ فصل ۶ — میانگین، میانه، پراکندگی است.
۳. گروهبندی روی دو ستون#
by_brand_city = df.groupby(["brand", "city"])["price"].mean().round(0)
print(by_brand_city.head(6))
brand city
اپل اصفهان 49400000.0
تبریز 39966667.0
تهران 47826667.0
شیراز 40133333.0
مشهد 45700000.0
اچ پی اصفهان 27400000.0
Name: price, dtype: float64
با دادنِ یک list از نامِ ستونها، هر ترکیب یک گروه میشود. نتیجه اندیسِ دوطبقه دارد: اول برند، بعد شهر.
این خوانا هست ولی برای مقایسه ایدهآل نیست — سخت است بفهمی کدام شهر برای همهٔ برندها گرانتر است. برای آن، شکلِ دوبعدی بهتر است.
۴. pivot_table: جدولِ دوبعدی#
pivot = df.pivot_table(values="price", index="brand", columns="year", aggfunc="mean").round(0)
print(pivot.iloc[:, :4])
year 2016 2017 2018 2019
brand
اپل 36000000.0 37450000.0 40925000.0 41300000.0
اچ پی 14600000.0 16540000.0 17100000.0 22166667.0
ایسوس 14683333.0 15150000.0 18085714.0 21242857.0
دل 13750000.0 18133333.0 19760000.0 19028571.0
لنوو 14355556.0 14525000.0 18440000.0 20233333.0
pivot_table چهار چیز میخواهد: چه چیزی را تجمیع کند (values)، چه چیزی ردیف شود (index)، چه چیزی ستون شود (columns)، و با چه تابعی (aggfunc).
فقط چهار ستونِ اول را نشان دادیم چون نُه سالِ کامل در صفحه جا نمیشود. حتی در همین چهار ستون، دو الگو دیده میشود: قیمتها با سال بالا میروند و اپل در همهٔ سالها بالاتر است.
✅ چک کن: جدولِ تو باید پنج ردیف داشته باشد (پنج برند) و هر عددش مثبت و در محدودهٔ ده تا شصت میلیون باشد. اگر خانهٔ خالی (
NaN) دیدی، یعنی آن ترکیبِ برند-سال هیچ آگهیای ندارد — که کاملاً عادی است و خودش یک اطلاعات است.
۵. روند در طولِ زمان#
by_year = df.groupby("year")["price"].mean().round(0)
print(by_year)
year
2016 17226667.0
2017 17786364.0
2018 21988000.0
2019 23173913.0
2020 25040000.0
2021 30970968.0
2022 30440000.0
2023 35060714.0
2024 36641667.0
Name: price, dtype: float64
یک روندِ تقریباً یکنواختِ صعودی. از ۱۷٫۲ میلیون در ۲۰۱۶ به ۳۶٫۶ میلیون در ۲۰۲۴ — بیش از دو برابر.
قبل از ادامه، جواب بده: این جدول ثابت میکند که لپتاپها گرانتر شدهاند؟ جواب: نه. چند توضیحِ دیگر هم با همین داده سازگارند: شاید لپتاپهای تازهتر مشخصاتِ بهتری دارند و ما داریم «کیفیت» را میبینیم نه «تورم»؛ شاید ترکیبِ برندها در سالهای اخیر عوض شده و اپلِ گران سهمِ بیشتری گرفته. یک روند در داده، یک الگوست، نه یک علت. فصلِ ۸ همین ترم دقیقاً به این میپردازد.
۶. یک خطای واقعی: گروهبندی روی ستونی که نیست#
df.groupby("Brand")["price"].mean()
KeyError: 'Brand'
حرفِ اولِ بزرگ. نامِ ستونها به بزرگی و کوچکیِ حروف حساساند و pandas هیچ حدسی نمیزند. این همان KeyError آشنای ترمِ یک است، فقط این بار روی یک ستون.
🔧 اگر کار نکرد: اولین کاری که باید بکنی
print(list(df.columns))است. در دادهٔ واقعی نامِ ستونها اغلب فاصلهٔ اضافی یا حرفِ بزرگ دارند و این را با چشم نمیبینی. یک عادتِ خوب برای شروعِ هر پروژه:df.columns = df.columns.str.strip().str.lower().
🤖 از دستیارت بپرس: «در pandas تفاوتِ
groupby().mean()وpivot_table()چیست؟ کِی کدام را بهکار ببرم؟» جوابش را با کاری که در بخشِ ۳ و ۴ کردیم مقایسه کن — هر دو یک محاسبه بودند با دو شکلِ نمایش. اگر دستیار ادعا کرد یکی سریعتر یا دقیقتر است، خودت روی همین داده امتحانش کن.
واژههای تازهٔ این فصل#
| کلمه | تلفظ به حروف فارسی | یعنی چه |
|---|---|---|
| groupby | گروپبای | تقسیمِ داده به گروه و گرفتنِ یک عدد از هر گروه |
| agg | اَگ | چند تابعِ تجمیع را همزمان اعمال میکند |
| pivot_table | پیوت تیبل | جدولِ دوبعدی از تجمیع؛ یک متغیر در ردیف، یکی در ستون |
| aggfunc | اَگفانک | تابعی که روی هر گروه اعمال میشود |
تمرینها
اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.
در فصل بعد#
عددها را داری، ولی جدولِ عدد بدترین راهِ دیدنِ یک روند است. آن نُه عددِ بخشِ ۵ را یک نمودارِ خطی در یک نگاه میگوید. فصلِ بعد matplotlib را میآورد و — مهمتر از دستورهایش — این سؤال را جواب میدهد: برای هر سؤالی که داری، کدام شکلِ نمودار درست است؟
به آخر این فصل رسیدی!
اگر ساختی و جواب داد، این دکمه مال توست.