آموزش کتابخانه pandas
این پست به آموزش کتابخانه pandas در پایتون اختصاص دارد. اگر با دادههای جدولی کار میکنید و به دنبال یک ابزار قدرتمند برای تحلیل و پردازش آنها هستید، پانداس یکی از بهترین گزینههاست. این کتابخانه به شما امکان میدهد دادهها را به صورت حرفهای پردازش کنید؛ بدون اینکه دچار پیچیدگیهای غیرضروری شوید. در این پست، از مفاهیم پایه تا مباحث پیشرفته پانداس را بررسی خواهیم کرد. با هوسم همراه باشید.
مقدمه
کتابخانه pandas یکی از مهمترین کتابخانههای حوزه دادهکاوی، علم داده و هوش مصنوعی است. این کتابخانه ابزارهای قدرتمندی برای کار با دادهها دارد. در این بخش، به معرفی کتابخانه پانداس میپردازیم و فرآیند نصب و ایمپورت (import) این کتابخانه را توضیح میدهیم. در ادامه به معرفی کاملتر و ویژگیهای کاربردیتر پانداس خواهیم پرداخت.
پانداس چیست؟
پانداس یک کتابخانه متنباز و قدرتمند در زبان برنامهنویسی پایتون است که برای تحلیل و مدیریت دادههای ساختاریافته (Structured Data) استفاده میشود.
به این تعریف مهم از پانداس دقت کنید:
Pandas is a Python library for data manipulation and analysis, providing powerful data structures and functions for working with structured data.
پانداس یک کتابخانه پایتون برای دستکاری و تحلیل دادهها است که ساختارهای دادهای قدرتمند و توابعی را برای کار با دادههای ساختاریافته ارائه میدهد.
خوب است که درباره هر یک از بخشهای مهم این تعریف بیشتر توضیح دهیم.
دستکاری و تحلیل دادهها با پانداس
اولین نکتهای که باید به آن توجه داشته باشیم این است که پانداس با دادهها کار میکند. در حوزه علم داده (Data Science) و هوش مصنوعی (AI)، دو مولفه کلیدی وجود دارد:
- داده (Data)
- مدل (Model)
در این آموزش، ما با مدل کاری نداریم، اما نیاز است که درباره دادهها اطلاعات بیشتری کسب کنیم. نکته مهم این است که برای آنکه یک مدل بتواند به درستی آموزش ببیند، داده خام باید به یک داده پردازششده و مناسب برای مدل تبدیل شود. دستکاری دادهها دقیقا به همین معنا است.
مرحله “تبدیل داده خام به دادهای مناسب و قابل استفاده برای مدل” را پیشپردازش دادهها (Data Preprocessing) مینامیم. ما دادهها را پیشپردازش میکنیم تا از نسخه خام به نسخهای ساختاریافته و قابل تحلیل تبدیل شوند. بنابراین، یکی از مهمترین وظایف پانداس، پیشپردازش و آمادهسازی دادهها است.
علاوه بر پیشپردازش داده، پانداس میتواند به ما کمک کند که اطلاعاتی ارزشمند از دادهها به دست آوریم و بر اساس این اطلاعات، تحلیل اکتشافی داده (Exploratory Data Analysis – EDA) را انجام دهیم. به کمک این تحلیل، میتوان الگوهای پنهان در دادهها را شناسایی و استخراج کرد.
ساختار داده (Data Structure)
منظور از ساختارهای دادهای چیست؟ احتمالا پیشتر در پایتون با لیست (List)، دیکشنری (Dictionary) و تاپل (Tuple) آشنا شدهاید یا در نامپای با آرایهها (Arrays) کار کردهاید. پانداس نیز دارای ساختارهای دادهای مخصوص به خود است که برای بارگذاری و ذخیرهسازی دادهها استفاده میشوند.
یکی از مهمترین این ساختارها، دیتافریم (DataFrame) است. هنگامی که دادههای ساختاریافته را در پانداس لود (Load) میکنیم، دادهها در قالب یک دیتافریم ذخیره میشوند. از این دیتافریم میتوان برای انجام عملیات مختلف مانند فیلتر کردن، گروهبندی، مرتبسازی، تغییر فرمت دادهها و بسیاری از پردازشهای دیگر استفاده کرد.
بنابراین، دیتافریمها امکان کار با دادههای ساختاریافته را برای ما فراهم میکنند. شاید این سوال برایتان پیش آمده که دادههای ساختاریافته به چه دادههایی گفته میشود و تفاوت آنها با دادههای غیرساختاریافته چیست؟
به طور کلی، دادههایی مانند فایلهای اکسل (Excel) یا CSV که دارای یک ساختار منظم هستند، دادههای ساختاریافته نامیده میشوند. تخصص اصلی پانداس، کار با دادههای ساختاریافته است.

در مقابل، دادههایی مانند تصاویر، صوت و متن، دادههای غیرساختاریافته محسوب میشوند. پانداس برای دادههای ساختاریافته و جدولی مناسب است. بنابراین فعلا به دادههای غیرساختاریافته کاری نداریم.
توابع قدرتمند پانداس
برای آنکه بتوانیم دادهها را تحلیل و پردازش کنیم، نیاز به توابع قدرتمند داریم. پانداس شامل مجموعهای از توابع آماده است که پردازش و تحلیل دادهها را آسان میکنند. برای مثال، میتوانیم با استفاده از پانداس، میانگین یک ستون مشخص را محاسبه کنیم. فرض کنید که یک دیتافریم شامل نمرات دانشآموزان داریم؛ پانداس میتواند میانگین نمرات را محاسبه کرده و مقدار آن را در یک ستون جدید ذخیره کند. شکل شماره 1 را در نظر بگیرید. میخواهیم با استفاده از برخی توابع پانداس میانگین نمرات دانشآموزان را محاسبه و در ستون جدیدی ذخیره کنیم. این کار به سادگی و با چند خط کد زیر قابل انجام است. هرچند شما هنوز با پانداس و دستورات آن آشنا نیستید اما نگران نباشید، در قسمتهای بعد به تفصیل، این دستورات را توضیح خواهیم داد.
grades = pd.read_excel('grades.xlsx') grades['Average'] = grades.iloc[:, 1:].mean(axis=1) grades.to_excel('average.xlsx')
نتیجه کد بالا، جدول زیر است:

بسیارخوب! تا اینجا به طور کلی با کتابخانه پانداس آشنا شدید. در بخشهای بعد توضیح میدهیم که چطور پانداس را با آناکوندا نصب کنید و آن را در محیط کدنویسی ایمپورت کنید.
نصب کتابخانه Pandas در پایتون
نصب پانداس با آناکوندا بسیار ساده است. میتوانید با انجام مراحل زیر آن را نصب کنید:
- آناکوندا را باز کنید.
- از منوی سمت چپ گزینه Environments را انتخاب کنید.
- محیط مورد نظر خود را که میخواهید پانداس در آن نصب شود انتخاب کنید.
- در بالای صفحه، از کنار گزینه Channels، گزینه Not installed را انتخاب کنید تا لیستی از پکیجهای نصبنشده نمایش داده شود.
- در قسمت بالای صفحه و در بخش Search Packages، کلمه Pandas را جستجو کنید.
سوال: بنظر شما چرا پکیجهای مرتبط زیادی نمایش داده میشود؟ پانداس یک کتابخانه پایهای و بسیار پرکاربرد است و به همین دلیل تعداد زیادی کتابخانه دیگر به آن وابسته یا مکمل آن هستند. بنابراین در لیست نتایج، علاوه بر خود پانداس، پکیجهای مرتبط دیگری نیز نمایش داده میشود.
- پس از یافتن Pandas، تیک مربوط به آن را بزنید و روی گزینه Apply کلیک کنید.
- صبر کنید تا آناکوندا ورژن مناسب پانداس و وابستگیهای مرتبط با آن را شناسایی کند. پس از نمایش لیست، دوباره گزینه Apply را بزنید.
- منتظر بمانید تا فرآیند نصب به پایان برسد.
به همین سادگی، پانداس روی محیط انتخابی شما نصب میشود!
ایمپورت پانداس
برای استفاده از پانداس، باید آن را ایمپورت کنیم. برای این کار کافی است دستور زیر را در نوتبوک یا اسکریپت خود اجرا کنید:
import pandas as pd
معمولاً از نام مستعار pd برای دسترسی سریعتر به توابع پانداس استفاده میشود. گاهی اوقات لازم است نسخهی دقیق کتابخانهای که نصب کردهاید را بدانید، زیرا ممکن است برخی ویژگیها یا توابع خاص، تنها در نسخههای مشخصی از کتابخانه وجود داشته باشند. برای بررسی نسخهی نصبشدهی پانداس، میتوانید از دستور زیر استفاده کنید:
print(pd.__version__)
2.2.2
بسیارخوب! تا اینجا به صورت مختصر با پانداس آشنا شدیم و توانستیم پانداس را نصب و ایمپورت کنیم. قبل از اینکه وارد بخشهای بعد شویم؛ بیایید در یک بخش کوتاه با دیتاستهای جدولی آشنا شویم.
دیتاستهای جدولی
دیتاستهای جدولی به عنوان یکی از رایجترین قالبهای ذخیرهسازی داده، نقشی کلیدی در تحلیل دادهها و یادگیری ماشین ایفا میکنند. شکل 3 نمونهای از یک دیتاست جدولی را نشان میدهد. این دیتاستها در یادگیری ماشین بسیار پرکاربرد هستند. بیاید بعضی از اصطلاحات مهم در دیتاست جدولی را معرفی کنیم.

اصطلاح اول
به هر کدام از سطرهای این دیتاست، سمپل (Sample) یا نمونه یا رکورد یا دیتا گفته میشود. اصولا سمپلها یا نمونهها در دیتاستهای جدولی مختلف (مانند شکل 3) سطر به سطر و زیر یکدیگر چیده میشوند.

اصطلاح دوم
به هر کدام از ستونها که یک ویژگی، خصوصیت یا پارامتر اندازهگیری از نمونهها را نمایش میدهد؛ فیچر (Feature) گفته میشود. به عنوان مثال در شکل 3، 4 فیچر وجود دارد.

سوال: چرا ستون اول و آخر، فیچر محسوب نمیشوند؟ سادهست! چون ستون اول صرفا به شماره سطرها اشاره میکند و ستون آخر هم دستهبندی گل را مشخص میکند بنابراین این ستونها، فیچر نیستند.
اصطلاح سوم:
به ستون آخر، که نشاندهنده هدف مساله (طبقهبندی گلها) است، تارگت (Target) یا برچسب (Label) گفته میشود.

بسیارعالی! حالا اگر با کتابخانه نامپای (Numpy) آشنا باشید، ممکن است سوالهایی برای شما پیش آمده باشد؛ مثلا، چرا باید از پانداس استفاده کنیم؟ داده جدولی بالا که شبیه ماتریس بود، خب میتوانم این ماتریس را با نامپای پردازش کنم؛ چه نیازی به پانداس دارم؟ صبر کنید، به این سوالها در بخش مقایسه پانداس و نامپای پاسخ دادیم…
مقایسه پانداس و نامپای
اگرچه پانداس از بسیاری از ایدهها و توابع نامپای بهره میبرد، اما بزرگترین تفاوت میان این دو کتابخانه در نوع دادهها و کاربرد آنها است.
پانداس، بهطور خاص برای کار با دادههای غیرهمگن و جدولی طراحی شده است. یعنی پانداس بهراحتی قادر است با دادههایی که در قالب جدول سازماندهی شدهاند و در آن، هر ستون میتواند دیتاتایپ متفاوت داشته باشد، کار کند. به عبارت دیگر، در یک دیتافریم پانداس، شما میتوانید دادههایی با انواع مختلف مانند اعداد صحیح، اعشاری، مقادیر بولین (True/False) و حتی رشتههای متنی (String) را در کنار هم در یک ستون قرار دهید.
حال، به این سوال میپردازیم که به چه دادههایی، دادههای غیرهمگن گفته میشود؟ دادههای غیرهمگن به دادههایی گفته میشود که مقادیر موجود در آنها از تایپهای مختلفی تشکیل شده باشد. به طور خاص، وقتی صحبت از دادههای جدولی میکنیم؛ منظور ما دادههایی است که در قالب جدول با ردیفها و ستونها سازماندهی شدهاند. در چنین جداولی، هر ستون ممکن است دیتاتایپ متفاوت داشته باشد. برای مثال، ممکن است در یک ستون اعداد صحیح داشته باشیم، در ستون دیگر اعداد اعشاری، در ستونی دیگر مقادیر بولین (True/False) و یا حتی رشتههای متنی ذخیره شده باشند.
در مقابل، نامپای بیشتر برای کار با دادههای همگن طراحی شده است. دادههای همگن به دادههایی گفته میشود که تمام مقادیر آنها از تایپ یکسانی برخوردار هستند. به عنوان مثال، در یک آرایه نامپای نمیتوان همزمان مقادیر عددی اعشاری و صحیح را ذخیره کرد، زیرا تمام مقادیر آرایه باید از نوع مشابهی باشند (مثلاً همه اعداد صحیح یا همه اعداد اعشاری). این ویژگی نامپای آن را برای محاسبات عددی و علمی که نیاز به دادههای همگن دارند، بسیار مناسب میکند، اما محدودیتی برای کار با دادههای پیچیده و متنوع ایجاد میکند.
پانداس بهویژه در کار با دادههای پیچیده و غیرهمگن و همچنین دادههای جدولی بسیار کارآمد است. به همین دلیل است که پانداس اغلب در پروژههای علم داده، یادگیری ماشین و تحلیل دادههای بزرگ که دادهها بهصورت جداول با انواع مختلف دادهها سازماندهی میشوند، کاربرد دارد. به عنوان مثال، شما میتوانید یک دیتافریم پانداس داشته باشید که در آن دادههای مختلف از تایپهای مختلف (اعداد صحیح، اعشاری، رشتهها و غیره) کنار هم قرار گرفته باشند بدون اینکه مشکلی در پردازش آنها پیش بیاید.
در نهایت، اگرچه نامپای برای پردازش دادههای عددی و همگن فوقالعاده است، پانداس با طراحی خاص خود برای دادههای غیرهمگن و جدولی ابزار بسیار کارآمدتری است. از این رو، اگر با دادههایی سر و کار دارید که انواع مختلف دادهها را در یک جدول شامل میشوند، پانداس گزینه بهتری است. در واقع، استفاده از پانداس برای کار با دادههای پیچیده و متنوع به شما این امکان را میدهد که عملیات پیچیدهتری را به سادگی انجام دهید و از انعطافپذیری بالای آن بهرهمند شوید.
عالی شد! تا اینجا در یک نگاه کلی با پانداس و تفاوت آن با نامپای آشنا شدیم. چطور است کمی عمیقتر به بررسی دیتااستراکچرهای پانداس بپردازیم؟ در بخش بعد قرار است با مهمترین دیتااستراکچرهای این کتابخانه آشنا شویم.
دیتااستراکچرهای پانداس
پانداس، دو دیتااستراکچر (Data Structure) اصلی و مهم دارد که بیشتر کارهای ما با همین دو ساختار انجام میشود. این دو دیتااستراکچر با یکدیگر در ارتباط هستند و بسیاری از عملیات پانداس بر پایه آنها انجام میشود:
- سریز (Series): سریز یک آرایه یکبعدی است که میتواند انواع مختلف دادهها (اعداد، رشتهها، مقادیر بولین و …) را در خود نگهداری کند. هرچند سریز از نظر عملکرد مشابه لیست (List) در پایتون یا آرایههای (Array) نامپای است، اما یک تفاوت مهم با آنها دارد و آن هم اینکه سریز دارای لیبل (Label) برای هر عنصر است. به زبان ساده، سریز مانند یک لیست است که هر عنصر آن، بهجای شمارههای پیشفرض (مانند اندیسهای 0، 1، 2 و …) دارای یک برچسب اختصاصی است، مشابه آنچه در دیکشنریها (Dictionary) در پایتون دیدهایم. این ویژگی باعث میشود که بتوانیم به هر مقدار بر اساس برچسب آن دسترسی داشته باشیم، نه صرفاً با شماره اندیس.
- دیتافریم (DataFrame): دیتافریم یکی دیگر از دیتااستراکچرهای پانداس است که پیشتر درباره آن صحبت کردیم. دیتافریم یک ساختار دوبعدی (مشابه یک جدول یا شیت اکسل) است که میتواند مقادیر با دیتاتایپهای متنوع را در ستونهای خود ذخیره کند.
هر دیتافریم در پانداس، دارای دو محور اصلی است:
- سطرها: که با ایندکس (Index) مشخص میشوند.
- ستونها: که هر ستون میتواند دیتاتایپ متفاوت داشته باشد (مانند عدد، رشته یا مقادیر بولین).
ارتباط سریز و دیتافریم:
یک نکته مهم این است که سریز، عنصر سازنده دیتافریم است. در واقع، اگر چندین سریز را در کنار هم قرار دهیم (ستونها) یا آنها را زیر هم قرار دهیم (ردیفها)، یک دیتافریم تشکیل میشود. به عنوان مثال در شکل 7، دیتافریم از کنار هم قرار گرفتن چند سریز در راستای ستونها ایجاد شده است. همانطور که میبینید مقادیر هر سریز و دیتافریم میتوانند دیتاتایپهای متنوعی داشته باشند.

بسیارخوب! تا اینجا درباره مقدمات پانداس صحبت و اهمیت و کارکردش را بررسی کردیم. حالا وقت آن رسیده است که کدنویسی را شروع کنیم. خوب است که شما نیز دست به کد باشید و همراه با من تمرین کنید.
سریز (Series) در پانداس
همانطور که در بخش قبل گفتیم، سریز یکی از دیتااستراکچرهای مهم پانداس است. در این بخش یاد میگیریم که چگونه یک سریز تعریف کنیم و چطور با آن کار کنیم.
هر سریز دارای 3 مولفه اصلی است:
- مقادیر (Values)
- ایندکس (Index)
- نام (Name)
در بین این 3 فاکتور، مقادیر و ایندکس اهمیت بیشتری دارند. بیایید هر کدام را دقیقتر بررسی کنیم.
جدول 1 یک سریز است. اما این دادهها چه چیزی را نشان میدهند؟
- Sara و Sophia و John و Ann، مقادیر آن هستند.
- اعداد 0 تا 3 ایندکسهای آن هستند که به هر مقدار اختصاص داده شدهاند.
میتوانیم از طریق ایندکسها به مقادیر دسترسی داشته باشیم. به عنوان مثال مقدار ایندکس شماره 0، Sara است، مقدار ایندکس شماره 1، Sophia است و به همین ترتیب… این روش، مشابه فراخوانی مقادیر در لیست است.
راجع به مقادیر و ایندکس صحبت کردیم؛ بنظر شما نام، کدام است؟ علاوه بر مقادیر و ایندکسها هر سریز میتواند یک نام داشته باشد. در جدول 1، نام سریز Name است که در بالای ستون نوشته شده است.
Name | |
Sara | 0 |
Sophia | 1 |
John | 2 |
Ann | 3 |
جدول 2 نیز یک سریز را نشان میدهد اما این بار تفاوتهایی با مثال قبل دارد. بیاید دقیقتر بررسی کنیم:
- مقادیر موجود در این سریز عبارتند از Sara، 88، 79 و 92.
- برخلاف سریز قبلی که ایندکسها عدد بودند اینجا ایندکسها متنی هستند: Name و Math و Calculus و Sport.
تفاوت این سریز با سریز مثال قبلی چیست؟ در سریز قبلی، هر مقدار دارای یک ایندکس عددی بود (مانند لیستهای پایتون)، بنابراین برای دسترسی به مقدار Sara از عدد 0 و برای مقدار Sophia از عدد 1 استفاده میکردیم. اما در این سریز، ایندکسها متنی هستند، یعنی به جای اعداد، از برچسبها (Labels) مانند Name و Math و Calculus و Sport استفاده شده است. این شباهت زیادی به دیکشنریهای پایتون دارد، زیرا در دیکشنریها نیز مقادیر با استفاده از کلیدهای متنی قابل دسترسی هستند.
چرا این موضوع مهم است؟ اینکه بتوانیم ایندکسها را خودمان مشخص کنیم، انعطافپذیری بالایی به ما میدهد. برای مثال، اگر در حال پردازش اطلاعات دانشآموزان باشیم، استفاده از نام دروس به عنوان ایندکس، خوانایی و دسترسی به دادهها را بسیار سادهتر میکند.
Sport | Calculus | Math | Name | |
92 | 79 | 88 | Sara | 0 |
عالیه! حالا که تفاوت ایندکسهای عددی و متنی را در سریز متوجه شدیم، بیایید یاد بگیریم که چگونه یک سریز در پانداس ایجاد کنیم.
ساخت سریز در پانداس
فرض کنید لیستی از نمرات دانشآموزان داریم که به نام grades تعریف شده است:
grades = [78, 98, 65, 97]
قصد داریم این لیست را به یک سریز تبدیل کنیم. برای این کار، کافی است از دستور pd.Series() استفاده کنیم و لیست grades را به عنوان ورودی به آن بدهیم:
grades_series = pd.Series(grades)
به همین سادگی! ما توانستیم یک سریز از لیست دادهها بسازیم. این یکی از مزایای پانداس است؛ میتوانیم به راحتی انواع دادههای متداول در پایتون را به دیتااستراکچرهای پانداس تبدیل کنیم.
بسیارخوب! در بخشهای قبل گفتیم که یکی از ویژگیهای دیتااستراکچرهای پانداس، غیرهمگن (heterogeneous) بودن آنها است. یعنی یک سریز میتواند دادههایی با انواع مختلف (str، bool، float، int و ..) را در خود جای دهد. به عنوان مثال، سریز زیر شامل عدد صحیح، عدد اعشاری، مقدار بولین و یک رشته است:
pd.Series([1.0, 2, True, "mahdi"])
0 1.0 1 2 2 True 3 mahdi dtype: object
پانداس بدون هیچ خطایی این سریز را میسازد، چون از نوع دادههای غیرهمگن پشتیبانی میکند. اما توجه داشته باشید که پانداس سعی میکند یک نوع داده مشترک (dtype) برای کل سریز انتخاب کند. اگر دادههای مختلفی مانند عدد و رشته را ترکیب کنیم، معمولا نوع داده سریز، آبجکت (object) خواهد شد.
برای دریافت مقادیر (Values) یک سریز میتوانیم از اتریبیوت values استفاده کنیم. به عنوان مثال برای دسترسی به مقادیر سریز grades_series از دستور زیر استفاده میکنیم:
grades_series.values
array([78, 98, 65, 97], dtype=int64)
خروجی این دستور چیست؟ خروجی این دستور، مقادیر سریز را به صورت یک آرایه نامپای نمایش میدهد. این نشان میدهد که پانداس و نامپای ارتباط نزدیکی با هم دارند و بسیاری از عملیات در پانداس براساس قابلیتهای نامپای انجام میشود.
همچنین برای دسترسی به ایندکسهای سریز از اتریبیوت index استفاده میشود:
grades_series.index
RangeIndex(start=0, stop=4, step=1)
خروجی این دستور چیست؟ خروجی این دستور یک کلاس RangeIndex است که نشاندهنده ایندکسهای عددی پیشفرض سریز است. این یعنی اگر ما لیستی را به pd.Series() بدهیم، پانداس به طور خودکار ایندکسها را از 0 تا n-1 تنظیم میکند.
یکی از ویژگیهای قدرتمند سریز در پانداس این است که میتوانیم ایندکسهای دلخواه خود را تنظیم کنیم. برای این کار، هنگام تعریف سریز، آرگومان index را (که به صورت دیفالت مقدارش None است) مقداردهی میکنیم و لیستی از اسامی ایندکسهای موردنظر خود را وارد میکنیم:
grades_with_index = pd.Series(grades, index=["farsi", " math", " sport", "art "])
Index(['farsi', ' math', ' sport', 'art '], dtype='object')
در اینجا، ایندکسهای 0، 1، 2، 3 دیگر استفاده نمیشوند. به جای آنها، ایندکسهایی که ما مشخص کردیم به کار رفتهاند.
سوال: بنظر شما اگر حالا مقادیر و ایندکسهای سریز grades_with_index را فراخوانی کنیم، چه خروجی خواهیم داشت؟
grades_with_index.values
array([78, 98, 65, 97], dtype=int64)
خروجی این دستور همان نمرات دانشآموزان خواهد بود، یعنی [78, 98, 65, 97].
grades_with_index.index
Index(['farsi', ' math', ' sport', 'art '], dtype='object')
اما این بار، ایندکسهای نمایش دادهشده دیگر عددی نیستند، بلکه همان ایندکسهایی هستند که ما تعریف کردهایم.
نکته مهم: برخلاف مقادیر در سریز، ایندکسها قابل تغییر (mutable) نیستند. این یعنی اگر یک سریز ساخته شود، دیگر نمیتوانیم ایندکسهای آن را مستقیما تغییر دهیم. بیاید این موضوع را با یک مثال بررسی کنیم:
grades_with_index.index[0] = "cal" grades_with_index.values[0] = 23
TypeError: Index does not support mutable operations
چه اتفاقی میافتد؟ وقتی مقدار را تغییر میدهیم، مقدار جدید جایگزین مقدار قبلی میشود و مشکلی پیش نمیآید. اما وقتی سعی میکنیم مقدار ایندکس را تغییر دهیم، پایتون خطا میدهد، زیرا ایندکسها در سریز immutable هستند. بنابراین اگر بخواهیم ایندکسها را تغییر دهیم، باید کل سریز را دوباره بسازیم.
در مثالهای قبل، سریزهایی را بدون نام (name) ایجاد کردیم. اما پانداس این امکان را میدهد که برای سریز یک نام اختصاص دهیم.
چه زمانی نام سریز مفید است؟
- وقتی چندین سریز در یک دیتافریم قرار میگیرند، نام سریز به عنوان نام ستون (Column Name) در نظر گرفته میشود.
- زمانی که دادهها را به صورت مستقل پردازش میکنیم، نام سریز کمک میکند تا بدانیم دادههای آن چه چیزی را نمایش میدهند.
در حال حاضر اگر سریز grades_with_index را بررسی کنیم، میبینیم که مقدار name در ابتدا خالی است:
grades_with_index.name
زیرا هنگام ایجاد این سریز، آرگومان name را مقداردهی نکردیم. برای این کار کافی است هنگام تعریف سریز، آرگومان name را مقداردهی کنیم:
grades_with_index = pd.Series(grades, index=["farsi", " math", " sport", "art "], name="Sara")
farsi 78 math 98 sport 65 art 97 Name: Sara, dtype: int64
اکنون این سریز دارای نام “Sara” است. اگر خروجی سریز را بررسی کنیم، میبینیم که نام سریز در بالای دادهها نمایش داده میشود. علاوه بر مقدار name، نوع داده (dtype) سریز نیز نمایش داده میشود.
چگونه dtype سریز را ببینیم؟ با استفاده از اتریبیوت dtype میتوانیم نوع دادههای سریز را مشاهده کنیم:
grades_with_index.dtype
dtype('int64')
آیا میتوانیم دیتایپ را تغییر دهیم؟ قبل از اینکه پاسخ این سوال را بدهیم، بهتر است ابتدا کمی درباره انواع دیتایپ در سریز صحبت کنیم.
انواع دیتایپ (dtype) در سریز
در پانداس، هر سریز دارای یک دیتایپ مشخص است که نشان میدهد مقادیر آن از چه نوعی هستند. این دیتایپ در عملکرد، فضای حافظه و سرعت پردازش دادهها تاثیر دارد. دیتایپهایی که اغلب در پانداس استفاده میشوند عبارتند از: int، float، bool، object. حال بیایید این دیتایپها را بررسی کنیم:
سریز با دیتایپ int (اعداد صحیح)
اگر تمام مقادیر یک سریز اعداد صحیح باشند، پانداس دیتایپ آن را int64 یا int32 (بسته به سیستم) در نظر میگیرد:
pd.Series([78, 98, 65, 97])
0 78 1 98 2 65 3 97 dtype: int64
چون تمام مقادیر عدد صحیح هستند، دیتایپ سریز int خواهد بود. این نوع داده کمترین فضای ممکن را در حافظه اشغال میکند و پردازش آن سریعتر است.
سریز با دیتایپ float (اعداد اعشاری)
اگر حداقل یکی از مقادیر سریز عدد اعشاری (float) باشد، تمام سریز به float تبدیل میشود:
pd.Series([78, 98, 65, 97.0])
0 78.0 1 98.0 2 65.0 3 97.0 dtype: float64
چون پانداس نمیتواند در یک سریز هم int داشته باشد و هم float؛ بنابراین برای جلوگیری از ناسازگاری، تمام مقادیر را به float تبدیل میکند.
سریز با دیتایپ bool (مقادیر منطقی)
اگر همه مقادیر سریز از نوع True و False باشند، دیتاتایپ آن bool خواهد شد.
pd.Series([False, True, False, False])
0 False 1 True 2 False 3 False dtype: bool
سریز با دیتایپ object (رشته و مقادیر ناهمگن)
دیتاتایپ object زمانی ایجاد میشود که:
- تمام مقادیر سریز از نوع رشته (str) باشند.
- مقادیر سریز ناهمگن باشند. (ترکیبی از چند دیتایپ باشند)
pd.Series(["A", "B", "C", "D"])
0 A 1 B 2 C 3 D dtype: object
pd.Series([2, 1, 15.0, True])
0 2 1 1 2 15.0 3 True dtype: object
بسیارخوب! با دیتایپهای سریز آشنا شدیم. حال برگردیم به سوال اصلیمان: چطور میتوانیم دیتایپ سریز را تغییر دهیم؟
یکی از آرگومانهای دستور ساخت سریز، دیتایپ (dtype) است. میتوانیم به راحتی آن را تنظیم کنیم؛ به عنوان مثال، لیست grades از نوع int است، برای تغییر دیتایپ آن به float به صورت زیر عمل میکنیم:
grades = [78, 98, 65, 97] pd.Series(grades, index=["farsi", "math", "sport", "art"], dtype=float)
farsi 78.0 math 98.0 sport 65.0 art 97.0 dtype: float64
اگر بخواهیم کنترل بیشتری روی دیتایپ داشته باشیم، میتوانیم از آرایههای نامپای استفاده کنیم:
pd.Series(grades, index=["farsi", "math", "sport", "art"], dtype=np.float32)
farsi 78.0 math 98.0 sport 65.0 art 97.0 dtype: float32
اگر بخواهیم سریز را به دیتایپ object تغییر دهیم:
pd.Series(grades, index=["farsi", "math", "sport", "art"], dtype="object")
farsi 78 math 98 sport 65 art 97 dtype: object
گاهی لازم است یک سریز از نوع float را به int تبدیل کنیم. این کار بهطور کلی ممکن است، اما اگر اعداد اعشاری اطلاعاتی داشته باشند که با تبدیل از دست برود، ممکن است به مشکل بخوریم!
اگر تمام مقادیر float، مقادیر صحیح باشند (یعنی مقدار اعشارشان صفر باشد)، میتوانیم آنها را بدون خطا به int تبدیل کنیم:
grades = [78, 98, 65, 97.0] pd.Series(grades, index=["farsi", "math", "sport", "art"], dtype=np.int32)
farsi 78 math 98 sport 65 art 97 dtype: int32
اما اگر حتی یک مقدار اعشاری واقعی داشته باشیم (مثلاً 97.5) تبدیل مستقیم به int خطا میدهد:
grades = [78, 98, 65, 97.5] pd.Series(grades, index=["farsi", "math", "sport", "art"], dtype=np.int32)
ValueError: Trying to coerce float values to integers
بسیار خوب! تا اینجا با نحوهی ساخت سریز در پانداس و انواع دیتایپ در سریز آشنا شدیم. اما چگونه میتوان به دادههای موجود در یک سریز دسترسی داشت؟ در بخش بعد، بهطور مفصل به روشهای مختلف اندیسدهی در سریز میپردازیم.
اندیسدهی در سریز
برای دسترسی به آیتمهای یک سریز میتوان از اندیسدهی (Indexing) و برش (Slicing) به شیوهای مشابه با لیستها در پایتون استفاده کرد. کافی است مقدار ایندکس موردنظر را درون براکت [ ] قرار دهیم.
بهعنوان مثال، اگر grades یک سریز باشد، میتوانیم مقادیر 78 و 98 را به این صورت فراخوانی کنیم:
grades = pd.Series([78, 98, 65, 97.5]) grades[0], grades[1]
(78.0, 98.0)
همچنین از اسلایسینگ برای انتخاب بخش خاصی از دادهها استفاده میشود:
grades[1:3] grades[:3] grades[2:] grades[0::2]
یک نکته مهم: در سریز برخلاف لیستهای معمولی، نمیتوان از اندیسدهی منفی برای دسترسی به عناصر استفاده کرد. دلیل این موضوع این است که ایندکسهای سریز میتوانند مقادیر دلخواهی داشته باشند و پانداس بهطور پیشفرض نمیداند که -1 باید به آخرین مقدار اشاره کند.
اما اگر -1 را به عنوان یکی از ایندکسهای سریز مشخص کنیم، میتوان از آن استفاده کرد:
grades = pd.Series([78, 98, 65, 97.5], index=[-1, 0, 1, 2]) grades[-1]
78.0
بنابراین، برای دسترسی به عناصر، نباید از اعداد منفی استفاده شود.
اگر ایندکسهای سریز از نوع رشته (str) باشند، چگونه باید آیتمها را فراخوانی کنیم؟ در این حالت، دسترسی به مقادیر سریز دقیقاً مانند دسترسی به مقادیر در یک دیکشنری انجام میشود؛ یعنی باید نام ایندکس موردنظر را در داخل براکت [ ] قرار دهیم:
grades = pd.Series([78, 98, 65, 97.5], index=["math", "sport", "art", "farsi"]) grades["math"]
78.0
تفاوت آن با دیکشنری در این است که سریز در اینجا یک دیکشنری مرتبشده (ordered dictionary) محسوب میشود. در دیکشنریها، ترتیب کلیدها تضمینشده نیست، اما در سریز ترتیب ایندکسها حفظ میشود؛ یعنی مقادیر دقیقاً به همان ترتیبی که تعریف شدهاند، باقی میمانند.
همچنین برای دسترسی به چندین مقدار در سریز با ایندکسهای رشتهای، میتوانیم لیستی از نام ایندکسها را داخل براکت [ ] قرار دهیم:
grades[["math", "sport"]]
math 78.0 sport 98.0 dtype: float64
روش دیگر برای دسترسی به مقادیر، استفاده از اتریبیوتهای سریز است. اگر نام ایندکسها مانند نام متغیرهای پایتون باشد (بدون فاصله و کاراکترهای خاص)، میتوان بهسادگی از نقطه (.) برای دسترسی به مقدار مربوطه استفاده کرد:
grades.math
78.0
نکته: این روش فقط زمانی کار میکند که نام ایندکس یک نام معتبر پایتونی باشد. اگر ایندکس شامل فاصله یا کاراکترهای خاص باشد، این روش قابل استفاده نخواهد بود و باید از روش قبل استفاده کنیم.
بسیارخوب! تا اینجا با دو روش اندیسدهی در سریز آشنا شدیم. هر دوی این روشها کاربردی هستند، اما هنگام استفاده از اتریبیوتهای سریز باید به دو نکته مهم توجه کنیم:
- از ایندکس بهعنوان اتریبیوت فقط زمانی استفاده میشود که ایندکسها، label باشند و یک نام سفارشی (custom index) برای آنها تعیین شده باشد.
- اگر ایندکسها عددی باشند، این روش قابل استفاده نخواهد بود.
grades = pd.Series([78, 98, 65, 97.5], index=[-1, 0, 1, 2]) grades.2
SyntaxError: invalid syntax
اگر اعداد را داخل کوتیشن بگذاریم؛ آیا میتوانیم در این حالت از عدد به عنوان اتریبیوت استفاده کنیم؟ خیر! حتی اگر ایندکس را بهصورت استرینگ (str) از عدد (“2”) تعریف کنیم، باز هم امکان استفاده از آن بهعنوان اتریبیوت وجود ندارد، زیرا در پایتون نام اتریبیوتها نمیتواند فقط عدد باشد.
grades = pd.Series([78, 98, 65, 97.5], index=[-1, 0, 1, "2"]) grades.2
SyntaxError: invalid syntax
پس چطور میتوان از اعداد در نام ایندکس، برای این روش استفاده کرد؟ برای این کار باید قبل از عدد، یک کاراکتر معتبر مثل _ یا یک حرف اضافه کنیم:
grades = pd.Series([78, 98, 65, 97.5], index=[-1, 0, "c", "_2"]) grades._2
97.5
در سریز میتوان مقدار یک ایندکس را تغییر داد (assignment). هر دو روش زیر معتبر است:
grades.c = 62 grades["c"] = 63
تبریک! بخش اندیسدهی در سریز هم به اتمام رسید. خوب است که شما هم دست به کد شوید و با تستکردن و آزمونخطا، چیزهای بیشتری یاد بگیرید. برای تکمیل این بحث، در بخش بعد، نکات تکمیلی در سریزها را بررسی خواهیم کرد.
دیدگاهتان را بنویسید