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

آخر این فصل میتوانی:
- یک فایلِ
CSVرا بخوانی و در چند خط بفهمی داخلش چیست - تفاوتِ
DataFrameوSeriesرا بگویی - با
info()وdtypesنوعِ هر ستون را ببینی و بفهمی چرا این اولین چیزی است که چک میکنی - با
describe()وvalue_counts()اولین تصویرِ داده را بگیری
قبل از شروع#
از فصل ۱: shape و dtype و اینکه هر ستون یک نوع دارد.
از ترمِ ۱ فصل ۴: dict — چون یک DataFrame در ذهنت چیزی شبیهِ «دیکشنریای از ستونها» است.
سلولِ راهاندازی: بالای نوتبوک یک سلول هست که فایلِ laptops.csv را میسازد — دادهٔ ساختگی ولی با همان کثیفیهایی که دادهٔ واقعی دارد. یک بار اجرایش کن. ساختگی بودنش عمدی است: اینطور نوتبوک همیشه و بدونِ اینترنت کار میکند و عددهای تو دقیقاً با کتاب میخوانند.
💡 نکته: آن سلول را باز کن و نگاهش کن، ولی اگر همهاش را نفهمیدی نگران نشو و رویش وقت نگذار. عمداً از ابزارهایی استفاده میکند که هنوز نرسیدهای — چند تایشان را در فصلهای ۴ و ۵ همین ترم میبینی و بقیه را در ترمِ ۵. کارش فقط ساختنِ فایل است؛ درسِ این فصل از خطِ
read_csvبه بعد شروع میشود.
📓 نوتبوک: نوتبوک این فصل را در Colab باز کن — همهٔ کدهای این فصل آماده و بهترتیب داخلش هست.
۱. خواندنِ فایل، و اولین نگاه#
import pandas as pd
df = pd.read_csv("laptops.csv")
print(df.shape)
print(list(df.columns))
print(df.head())
(244, 5)
['brand', 'city', 'year', 'ram_gb', 'price']
brand city year ram_gb price
0 اپل اصفهان 2021 32.0 58,500,000
1 لنوو مشهد 2019 16.0 23,400,000
2 اپل تهران 2024 8.0 54,200,000
3 ایسوس مشهد 2023 8.0 32900000
4 لنوو تهران 2019 8.0 20,500,000
read_csv یک فایلِ متنیِ ویرگولجدا را میخواند و به DataFrame تبدیل میکند. نامِ df یک قراردادِ جهانی است و در هر کدی که بخوانی همین را میبینی.
سه چیز را همین حالا ببین:
shapeمیگوید ۲۴۴ ردیف و ۵ ستون. عادت کن این اولین چیزی باشد که چاپ میکنی.- ستونِ سمتِ چپ که از صفر میشمارد، اندیس (
index) است. جزوِ ستونها نیست؛ شناسهٔ ردیف است. - و حالا به ستونِ
priceنگاه کن. بعضی مقدارها ویرگولِ هزارگان دارند و بعضی نه. این یک هشدارِ جدی است.
۲. Series در برابر DataFrame#
one_column = df["price"]
two_columns = df[["brand", "price"]]
print(type(one_column))
print(type(two_columns))
print(one_column.head(3))
<class 'pandas.Series'>
<class 'pandas.DataFrame'>
0 58,500,000
1 23,400,000
2 54,200,000
Name: price, dtype: str
دو تکه از این خروجی به نسخهٔ pandas بستگی دارند و ممکن است روی دستگاهِ تو کمی متفاوت باشند: مسیرِ کاملِ نوع (در نسخههای قدیمیتر <class 'pandas.core.series.Series'>) و نامِ نوعِ ستونِ متنی (در نسخههای قدیمیتر object بهجای str). چیزی که در همهٔ نسخهها یکی است، همین دو جمله است:
df["price"]با یک کروشه یک ستونِ تنها میدهد که نوعشSeriesاست — یک آرایهٔ تکبعدی با اندیس و نام.df[["brand", "price"]]با دو کروشه یکDataFrameمیدهد. کروشهٔ داخلی در واقع یکlistاز نامِ ستونهاست.
این تفاوت را یاد بگیر، چون خیلی از خطاهای بعدی از همین میآید: بعضی توابع Series میخواهند و بعضی DataFrame.
✅ چک کن: آن خطِ آخرِ خروجی —
Name: price, dtype: ...— بخشی از خودِSeriesاست. اگر آن را ندیدی، احتمالاً دو کروشه گذاشتهای وDataFrameگرفتهای.
۳. dtypes: اولین چیزی که باید چک کنی#
print(df.dtypes)
brand str
city str
year int64
ram_gb float64
price str
dtype: object
شکلِ دقیقِ این خروجی به نسخهٔ pandas بستگی دارد — در نسخههای قدیمیتر بهجای str کلمهٔ object را میبینی. چیزی که مهم است و در همهٔ نسخهها یکی است، این جمله است:
ستونِ price عدد نیست، متن است.
و این یعنی هیچ محاسبهای رویش کار نمیکند. df["price"].mean() یا خطا میدهد یا — بدتر — چیزی میدهد که معنا ندارد. دلیلش را در بخشِ ۱ دیدی: آن ویرگولهای هزارگان. read_csv وقتی میبیند بعضی مقدارها عدد نیستند، کلِ ستون را متن میکند و هیچ هشداری هم نمیدهد.
ram_gb هم float64 است، نه int64. چرا؟ چون خانههای خالی دارد و در pandas مقدارِ گمشده یک عددِ اعشاریِ خاص است، پس کلِ ستون اعشاری میشود.
⚠️ مواظب باش: این پرکاربردترین منبعِ باگِ خاموش در کارِ داده است. یک ستونِ «عددی» که در واقع متن است، در هر محاسبهای نتیجهٔ غلط یا خطا میدهد — و اگر مرتبسازی کنی،
"9,000,000"قبل از"58,500,000"میآید چون الفبایی مقایسه میشوند نه عددی.dtypesرا همیشه، بلافاصله بعد ازread_csv، نگاه کن.
۴. info(): همهچیز در یک نگاه#
df.info()
<class 'pandas.DataFrame'>
RangeIndex: 244 entries, 0 to 243
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 brand 244 non-null str
1 city 244 non-null str
2 year 244 non-null int64
3 ram_gb 217 non-null float64
4 price 244 non-null str
dtypes: float64(1), int64(1), str(3)
memory usage: 9.7 KB
ستونِ Non-Null Count مهمترین بخشِ این خروجی است: چهار ستون ۲۴۴ مقدار دارند، ولی ram_gb فقط ۲۱۷ تا. یعنی ۲۷ خانهٔ خالی.
پس تا اینجا بدونِ نوشتنِ یک خط پاکسازی، دو مشکل پیدا کردی: ستونِ قیمت متن است، و ستونِ حافظه خانهٔ خالی دارد. سومی را بخشِ بعد نشان میدهد.
۵. describe() و value_counts(): اولین تصویر#
print(df.describe())
year ram_gb
count 244.000000 217.000000
mean 2020.663934 11.981567
std 12.202415 7.488240
min 1998.000000 4.000000
25% 2018.000000 8.000000
50% 2020.000000 8.000000
75% 2022.000000 16.000000
max 2205.000000 32.000000
describe() برای هر ستونِ عددی خلاصهٔ آماری میدهد. سه چیزِ گفتنی:
- فقط دو ستون آمد، چون بقیه عددی نیستند. نبودنِ
priceدر این جدول خودش یک یافته است. - به
maxستونِyearنگاه کن: ۲۲۰۵. یک لپتاپ از سالِ ۲۲۰۵. وminهم ۱۹۹۸ است. این سومین مشکل است — مقدارِ غیرممکن. stdستونِyearبرابرِ ۱۲٫۲ است، در حالی که ۷۵ درصدِ داده بینِ ۲۰۱۸ و ۲۰۲۲ است. یک مقدارِ پرتِ تنها، انحرافِ معیار را منفجر میکند.
🌱 ریشهاش کجاست:
25%و50%و75%را چارک میگویند: عددی که یکچهارم، نصف، و سهچهارمِ داده زیرِ آن است.50%همان میانه است. اگر میخواهی بدانی چرا میانه در برابرِ مقدارِ پرت مقاوم است ولی میانگین نه — دقیقاً همان چیزی که در همین خروجی میبینی — ریشه، ترم ۶ فصل ۶ بازش میکند.
برای ستونهای غیرعددی، ابزارِ درست value_counts است:
print(df["brand"].value_counts())
brand
ایسوس 67
لنوو 51
دل 46
اچ پی 36
اپل 28
ايسوس 12
اچ پي 4
Name: count, dtype: int64
هفت برند؟ ولی فقط پنج برند وجود دارد. با دقت نگاه کن: «ایسوس» و «ايسوس» دو ردیفِ جدا هستند، و همینطور «اچ پی» و «اچ پي». تفاوتشان یک حرف است که چشمِ تو آن را یکسان میبیند — «ی» فارسی در برابرِ «ي» عربی.
این چهارمین مشکل است، و بدترینشان: هیچ خطایی نمیدهد، در info() دیده نمیشود، و اگر بخواهی میانگینِ قیمت را برندبهبرند حساب کنی، ۱۲ ردیفِ «ایسوس» در گروهِ اشتباه میروند.
📏 اندازه بگیر: توجه کن که این چهار مشکل را با چهار دستور پیدا کردیم:
head،dtypes،info،value_counts. هیچکدام هوشمندانه نبودند؛ فقط نگاه کردیم. این دقیقاً معنای قانونِ اولِ دوره است: «اول داده را ببین». کسی که مستقیم سراغِ مدل برود، هر چهارتای اینها را با خودش وارد مدل میکند و بعد ماهها دنبالِ دلیلِ نتیجهٔ عجیب میگردد.
۶. یک خطای واقعی: محاسبه روی ستونِ متنی#
print(df["price"].mean())
TypeError: Could not convert string '58,500,000...' to numeric
دقیقاً همان چیزی که پیشبینی کردیم. pandas نمیتواند میانگینِ یک ستونِ متنی را بگیرد.
نکتهٔ آموزنده این است که اینجا خوششانس بودیم که خطا گرفتیم. حالتِ خطرناکتر وقتی است که عملیاتی روی متن هم تعریف شده باشد و بیسروصدا نتیجهٔ بیمعنا بدهد:
print(df["price"].max())
print(df["price"].sort_values().head(3).tolist())
9100000
['10000000', '10000000', '11,200,000']
max جواب داد — و جوابش غلط است. گرانترین لپتاپ ۹٫۱ میلیون نیست؛ در بخشِ ۱ یکی به قیمتِ ۵۸ میلیون دیدیم. ولی چون مقایسه الفبایی انجام شد، متنی که با 9 شروع میشود از متنی که با 5 شروع میشود بزرگتر شد.
خروجیِ مرتبسازی هم همانقدر بیمعناست: '11,200,000' بعد از '10000000' آمده، و ارزانترینها اصلاً اینها نیستند. دو مقدار که یکی ویرگول دارد و یکی ندارد، حتی با هم قابلِ مقایسه نیستند.
(آن .tolist() آخرِ خط کارِ مهمی نمیکند: ستون را به یک list سادهٔ پایتون تبدیل میکند تا سه مقدار در یک خط و کنارِ هم چاپ شوند، بهجای شکلِ چندخطیِ Series.)
🔧 اگر کار نکرد: اگر جایی عددی گرفتی که با شهودت جور درنمیآید، اول
dtypeآن ستون را چاپ کن. یک ستونِ متنی که فکر میکنی عددی است، بیسروصداترین باگِ کلِ کارِ داده است. راهِ رفعش را در فصلِ ۵ کامل میبینی.
🤖 از دستیارت بپرس: «چه دلایلی باعث میشود
read_csvیک ستونِ عددی را بهعنوان متن بخواند؟ فقط فهرست کن.» جوابش احتمالاً ویرگولِ هزارگان، واحدِ چسبیده مثل «تومان»، رشتهٔ خالی و علامتِ سؤال را میآورد. برای هر مورد که گفت، یک نمونهٔ کوچک بساز و امتحان کن واقعاً همین اتفاق میافتد یا نه.
واژههای تازهٔ این فصل#
| کلمه | تلفظ به حروف فارسی | یعنی چه |
|---|---|---|
| pandas | پانداس | کتابخانهٔ اصلیِ کار با دادهٔ جدولی در پایتون |
| DataFrame | دیتافریم | جدول: چند ستونِ نامدار با یک اندیسِ مشترک |
| Series | سریز | یک ستونِ تنها؛ آرایهٔ تکبعدی با اندیس و نام |
| index | ایندِکس | شناسهٔ ردیفها؛ جزوِ ستونها نیست |
| value_counts | ولیو کانتس | شمارشِ تکرارِ هر مقدار در یک ستون |
تمرینها
اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.
در فصل بعد#
حالا میدانی داخلِ جدول چه خبر است. فصلِ بعد یاد میگیری از داخلش چیزی بیرون بکشی: ستونِ خاص، ردیفهایی که شرطی دارند، مرتبشده بر اساسِ چیزی که برایت مهم است، و ستونِ تازهای که خودت میسازی. همان ماسکِ شرطیِ فصلِ ۲ برمیگردد — این بار روی یک جدولِ واقعی.
به آخر این فصل رسیدی!
اگر ساختی و جواب داد، این دکمه مال توست.