۳۰ آذر ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

نحوه استفاده از پاندا برای تجزیه و تحلیل داده ها در پایتون

پانداها بارگذاری سریع، دستکاری، تراز کردن، ادغام و حتی تجسم جداول داده را مستقیماً در پایتون آسان می کند.

پانداها بارگذاری سریع، دستکاری، تراز کردن، ادغام و حتی تجسم جداول داده را مستقیماً در پایتون آسان می کند.

وقتی نوبت به کار با داده‌ها به شکل جدولی می‌رسد، بیشتر مردم به صفحه‌گسترده دسترسی پیدا می‌کنند. این انتخاب بدی نیست: مایکروسافت اکسل و برنامه‌های مشابه با قابلیت‌هایی برای ماساژ جداول داده آشنا و پر شده‌اند. اما اگر می خواهید کنترل، دقت و قدرت بیشتری نسبت به اکسل به تنهایی ارائه می دهد، چه؟

در این صورت، کتابخانه Pandas منبع باز برای Python ممکن است همان چیزی باشد که شما به دنبال آن هستید. این پایتون را با انواع داده های جدید برای بارگیری سریع داده ها از منابع جدولی و برای دستکاری، تراز کردن، ادغام و انجام سایر پردازش ها در مقیاس، تجهیز می کند.

اولین مجموعه داده پانداهای شما

پانداها بخشی از کتابخانه استاندارد پایتون نیستند. این یک پروژه شخص ثالث است، بنابراین باید آن را در زمان اجرای پایتون خود با پاندای نصب pip نصب کنید. پس از نصب، می توانید آن را با وارد کردن پانداها به پایتون وارد کنید.

Pandas دو نوع داده جدید در اختیار شما قرار می دهد: Series و DataFrame. DataFrame کل صفحه گسترده یا داده های مستطیلی شما را نشان می دهد، در حالی که Series یک ستون از DataFrame است. همچنین می توانید پانداهای DataFrame را به عنوان فرهنگ لغت یا مجموعه ای از اشیاء Series در نظر بگیرید. بعداً خواهید دید که می‌توانید از روش‌های دیکشنری و فهرست‌مانند برای یافتن عناصر در DataFrame استفاده کنید.

شما معمولاً با وارد کردن داده ها در قالب دیگری با پانداها کار می کنید. یک فرمت رایج داده های جدولی خارجی، CSV است، یک فایل متنی با مقادیر جدا شده با کاما. اگر CSV دم دستی دارید، می توانید از آن استفاده کنید. برای این مقاله، از گزیده‌ای از مجموعه داده‌های Gapminder استفاده می‌کنیم که توسط جنیفر برایان از دانشگاه بریتیش کلمبیا.

برای شروع استفاده از پانداها، ابتدا کتابخانه را وارد می کنیم. توجه داشته باشید که استفاده از نام مستعار کتابخانه پانداها به عنوان pd برای ذخیره مقداری تایپ، یک روش معمول است:

import pandas as pd

برای شروع کار با داده‌های نمونه در قالب CSV، می‌توانیم با استفاده از تابع pd.read_csv آن را به‌عنوان یک قاب داده بارگیری کنیم:


df = pd.read_csv("./gapminder/inst/extdata/gapminder.tsv", sep='\t')

پارامتر sep به ما امکان می‌دهد مشخص کنیم که این فایل خاص تقسیم‌بندی شده با برگه باشد نه با کاما.

هنگامی که داده ها بارگیری شدند، می توانید با استفاده از روش .head() در قالب داده، به قالب بندی آن نگاه کنید تا مطمئن شوید که به درستی بارگیری شده است:


print(df.head())
       country continent  year  lifeExp       pop   gdpPercap
۰  Afghanistan      Asia  1952   28.801   8425333  779.445314
۱  Afghanistan      Asia  1957   30.332   9240934  820.853030
۲  Afghanistan      Asia  1962   31.997  10267083  853.100710
۳  Afghanistan      Asia  1967   34.020  11537966  836.197138
۴  Afghanistan      Asia  1972   36.088  13079460  739.981106

اشیاء قاب داده دارای ویژگی shape هستند که تعداد ردیف‌ها و ستون‌ها را در قاب داده گزارش می‌کند:


print(df.shape)
(۱۷۰۴, ۶) # rows, cols

برای فهرست کردن نام خود ستون‌ها، از .columns استفاده کنید:


print(df.columns)
Index(['country', 'continent', 'year', 'lifeExp',
'pop', 'gdpPercap'], dtype='object')

فریم‌های داده در پانداها تقریباً مانند قاب‌های داده در زبان‌های دیگر مانند Julia و R کار می‌کنند. هر ستون، یا Series، باید از یک نوع باشد، در حالی که هر ردیف می‌تواند دارای انواع ترکیبی باشد. به عنوان مثال، در مثال فعلی، ستون country همیشه یک رشته خواهد بود و ستون year همیشه یک عدد صحیح است. ما می‌توانیم این را با استفاده از .dtypes برای فهرست کردن نوع داده‌های هر ستون تأیید کنیم:


print(df.dtypes)
country object
continent object
year int64
lifeExp float64
pop int64
gdpPercap float64
dtype: object

برای تفکیک واضح تر انواع قاب داده خود، می توانید از .info() استفاده کنید:


df.info() # information is written to console, so no print required
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1704 entries, 0 to 1703
Data columns (total 6 columns):
 #   Column     Non-Null Count  Dtype
---  ------     --------------  -----
 ۰   country    1704 non-null   object
 ۱   continent  1704 non-null   object
 ۲   year       1704 non-null   int64
 ۳   lifeExp    1704 non-null   float64
 ۴   pop        1704 non-null   int64
 ۵   gdpPercap  1704 non-null   float64
dtypes: float64(2), int64(2), object(2)
memory usage: 80.0+ KB

هر نوع داده پاندا به یک نوع داده بومی پایتون نگاشت:

  • object به عنوان یک نوع Python str استفاده می‌شود.
  • int64 به عنوان پایتون int استفاده می‌شود. توجه داشته باشید که همه intهای پایتون را نمی توان به انواع int64 تبدیل کرد. هر چیزی بزرگتر از (۲ ** ۶۳)-۱ به int64 تبدیل نمی‌شود.
  • float64 به عنوان یک پایتون float استفاده می‌شود (که یک float ۶۴ بیتی است).
  • datetime64 به عنوان یک شی datetime.datetime پایتون استفاده می شود. توجه داشته باشید که Pandas به طور خودکار سعی نمی کند چیزهایی را که شبیه تاریخ هستند به مقادیر تاریخ تبدیل کند. شما باید به پانداها بگویید که می خواهید این کار را برای یک ستون خاص انجام دهید .
نحوه استفاده از async و await در جاوا اسکریپت

ستون‌ها، ردیف‌ها و سلول‌های پاندا

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

رویکرد بهتر این است که به زیر مجموعه‌های داده نگاه کنیم، همانطور که با df.head() انجام دادیم، اما با کنترل بیشتر. Pandas به شما امکان می دهد با استفاده از نحو موجود پایتون برای نمایه سازی و ایجاد برش، گزیده هایی از دیتافریم بسازید.

استخراج ستون های پاندا

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


# extract the column "country" into its own dataframe
country_df = df["country"]
# show the first five rows
print(country_df.head())
| ۰ Afghanistan
| ۱ Afghanistan
| ۲ Afghanistan
| ۳ Afghanistan
| ۴ Afghanistan
Name: country, dtype: object

# show the last five rows
print(country_df.tail())
| ۱۶۹۹  Zimbabwe
| ۱۷۰۰  Zimbabwe
| ۱۷۰۱  Zimbabwe
| ۱۷۰۲  Zimbabwe
| ۱۷۰۳  Zimbabwe
| Name: country, dtype: object

اگر می خواهید چندین ستون استخراج کنید، فهرستی از نام ستون ها را ارسال کنید:


# Looking at country, continent, and year
subset = df[['country', 'continent', 'year']]

print(subset.head())

       country continent  year
| ۰  Afghanistan    Asia  1952
| ۱  Afghanistan    Asia  1957
| ۲  Afghanistan    Asia  1962
| ۳  Afghanistan    Asia  1967
| ۴  Afghanistan    Asia  1972
print(subset.tail())

         country continent    year
| ۱۶۹۹  Zimbabwe    Africa    1987
| ۱۷۰۰  Zimbabwe    Africa    1992
| ۱۷۰۱  Zimbabwe    Africa    1997
| ۱۷۰۲  Zimbabwe    Africa    2002
| ۱۷۰۳  Zimbabwe    Africa    2007

زیر مجموعه ردیف‌ها

اگر می‌خواهید ردیف‌ها را از یک دیتافریم استخراج کنید، می‌توانید از یکی از دو روش استفاده کنید.

.iloc[]  ساده‌ترین روش است. این سطرها را بر اساس موقعیت آنها استخراج می کند که از ۰ شروع می شود. برای واکشی ردیف اول در مثال قاب داده بالا، باید از df.iloc[0] استفاده کنید.

اگر می‌خواهید طیف وسیعی از ردیف‌ها را واکشی کنید، می‌توانید از .iloc[] با نحو برش پایتون استفاده کنید. به عنوان مثال، برای ۱۰ ردیف اول، از df.iloc[0:10] استفاده می کنید. و اگر می‌خواهید ۱۰ ردیف آخر را به ترتیب معکوس بدست آورید، از df.iloc[::-1] استفاده می‌کنید.

اگر می‌خواهید ردیف‌های خاصی را استخراج کنید، می‌توانید از فهرستی از شناسه‌های ردیف استفاده کنید. برای مثال، df.iloc[[0,1,2,5,7,10,12]]. (به دو پرانتز توجه کنید—یعنی یک لیست به عنوان اولین آرگومان ارائه می دهید.)

وقتی باز بودن مهم نیست

یک راه دیگر برای استخراج ردیف ها با .loc[] است. این یک زیر مجموعه را بر اساس برچسب‌ها برای ردیف‌ها استخراج می‌کند. به‌طور پیش‌فرض، ردیف‌ها با یک عدد صحیح افزایشی که با ۰ شروع می‌شود برچسب‌گذاری می‌شوند. اما داده‌ها را می‌توان به صورت دستی با تنظیم ویژگی .index. dataframe.

به عنوان مثال، اگر بخواهیم قاب داده بالا را دوباره فهرست بندی کنیم به طوری که هر ردیف دارای شاخصی با استفاده از مضرب ۱۰۰ باشد، می توانیم از df.index = range(0, len(df)*100, 100 استفاده کنیم. ). سپس، اگر از df.loc[100] استفاده کنیم، ردیف دوم را دریافت می‌کنیم.

ستون‌های زیر مجموعه

اگر می‌خواهید فقط زیرمجموعه خاصی از ستون‌ها را به همراه برش‌های ردیف خود بازیابی کنید، این کار را با ارسال فهرستی از ستون‌ها به عنوان آرگومان دوم انجام می‌دهید: 

df.loc[[ ردیف‌ها]، [ستون‌ها]] 

به عنوان مثال، با مجموعه داده فوق، اگر بخواهیم فقط ستون های کشور و سال را برای همه ردیف ها دریافت کنیم، این کار را انجام می دهیم:

df.loc[:, ["country","year"]]

: در موقعیت اول به معنای “همه ردیف‌ها” است (این نحو برش پایتون است). لیست ستون ها بعد از کاما قرار می گیرد.

همچنین می‌توانید هنگام استفاده از .iloc، ستون‌ها را بر اساس موقعیت مشخص کنید:

df.iloc[:, [0,2]]

یا، برای دریافت فقط سه ستون اول:

df.iloc[:, 0:3]

همه این رویکردها را می‌توان ترکیب کرد، تا زمانی که به یاد داشته باشید loc برای برچسب‌ها و نام ستون‌ها و iloc برای نمایه‌های عددی استفاده می‌شود. موارد زیر به پانداها می‌گوید که ۱۰۰ سطر اول را با برچسب‌های عددی خود استخراج کنند و سپس از that سه ستون اول را با نمایه‌هایشان استخراج کنند:

df.loc[0:100].iloc[:, 0:3]

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

محاسبات گروهی و انبوه

صفحه‌گسترده‌ها و کتابخانه‌های خردکننده اعداد همگی با روش‌هایی برای تولید آمار در مورد داده‌ها ارائه می‌شوند. دوباره داده های Gapminder را در نظر بگیرید:


print(df.head(n=10))
|    country      continent  year  lifeExp  pop       gdpPercap
| ۰  Afghanistan  Asia       1952  28.801    8425333  779.445314
| ۱  Afghanistan  Asia       1957  30.332    9240934  820.853030
| ۲  Afghanistan  Asia       1962  31.997   10267083  853.100710
| ۳  Afghanistan  Asia       1967  34.020   11537966  836.197138
| ۴  Afghanistan  Asia       1972  36.088   13079460  739.981106
| ۵  Afghanistan  Asia       1977  38.438   14880372  786.113360
| ۶  Afghanistan  Asia       1982  39.854   12881816  978.011439
| ۷  Afghanistan  Asia       1987  40.822   13867957  852.395945
| ۸  Afghanistan  Asia       1992  41.674   16317921  649.341395
| ۹  Afghanistan  Asia       1997  41.763   22227415  635.341351

در اینجا چند نمونه از سؤالاتی است که می‌توانیم درباره این داده بپرسیم:

  1. متوسط ​​امید به زندگی برای هر سال در این داده ها چقدر است؟
  2. اگر میانگین سال‌ها و قاره‌ها را بخواهم چه می‌شود؟
  3. چگونه شمارش کنم که چند کشور در این داده ها در هر قاره وجود دارد؟

روش پاسخ به این سؤالات با پانداها این است که یک محاسبه  گروهی یا جمعی انجام دهید. می‌توانیم داده‌ها را در خطوط مشخصی تقسیم کنیم، مقداری محاسبات را برای هر بخش تقسیم شده اعمال کنیم، و سپس نتایج را دوباره در یک دیتافریم جدید ترکیب کنیم.

گروه‌بندی به معنای شمارش است

اولین روشی که برای این کار استفاده می‌کنیم، عملیات df.groupby()  Pandas است. ما ستونی ارائه می دهیم که می خواهیم داده ها را بر اساس:

تقسیم کنیم

df.groupby("year")

این به ما امکان می‌دهد تا همه ردیف‌های دارای مقدار سال یکسان را با هم، به‌عنوان یک شی مجزا از خود چارچوب داده، در نظر بگیریم.

از آنجا، می‌توانیم از ستون “امید به زندگی” استفاده کنیم و میانگین سالانه آن را محاسبه کنیم:


print(df.groupby('year')['lifeExp'].mean())
year
۱۹۵۲ ۴۹.۰۵۷۶۲۰
۱۹۵۷ ۵۱.۵۰۷۴۰۱
۱۹۶۲ ۵۳.۶۰۹۲۴۹
۱۹۶۷ ۵۵.۶۷۸۲۹۰
۱۹۷۲ ۵۷.۶۴۷۳۸۶
۱۹۷۷ ۵۹.۵۷۰۱۵۷
۱۹۸۲ ۶۱.۵۳۳۱۹۷
۱۹۸۷ ۶۳.۲۱۲۶۱۳
۱۹۹۲ ۶۴.۱۶۰۳۳۸
۱۹۹۷ ۶۵.۰۱۴۶۷۶
۲۰۰۲ ۶۵.۶۹۴۹۲۳
۲۰۰۷ ۶۷.۰۰۷۴۲۳

این میانگین امید به زندگی برای همه جمعیت‌ها را بر اساس سال به ما می‌دهد. ما می‌توانیم همان نوع محاسبات را برای جمعیت و تولید ناخالص داخلی در سال انجام دهیم:


print(df.groupby('year')['pop'].mean())
print(df.groupby('year')['gdpPercap'].mean())

تا اینجا، خیلی خوب است. اما اگر بخواهیم داده های خود را بر اساس بیش از یک ستون گروه بندی کنیم، چه؟ ما می توانیم این کار را با عبور دادن ستون ها در لیست ها انجام دهیم:


print(df.groupby(['year', 'continent'])
  [['lifeExp', 'gdpPercap']].mean())
                  lifeExp     gdpPercap
year continent
۱۹۵۲ Africa     39.135500   1252.572466
     Americas   53.279840   4079.062552
     Asia       46.314394   5195.484004
     Europe     64.408500   5661.057435
     Oceania    69.255000  10298.085650
۱۹۵۷ Africa     41.266346   1385.236062
     Americas   55.960280   4616.043733
     Asia       49.318544   5787.732940
     Europe     66.703067   6963.012816
     Oceania    70.295000  11598.522455
۱۹۶۲ Africa     43.319442   1598.078825
     Americas   58.398760   4901.541870
     Asia       51.563223   5729.369625
     Europe     68.539233   8365.486814
     Oceania    71.085000  12696.452430

این عملیات .groupby() داده های ما را می گیرد و ابتدا بر اساس سال و سپس بر اساس قاره گروه بندی می کند. سپس مقادیر میانگین را از ستون‌های امید به زندگی و تولید ناخالص داخلی تولید می‌کند. به این ترتیب، می توانید گروه هایی را در داده های خود ایجاد کنید و نحوه ارائه و محاسبه آنها را رتبه بندی کنید.

ایستگاه های کاری مبتنی بر ابر Microsoft Dev Box وارد پیش نمایش عمومی می شوند

اگر می‌خواهید نتایج را در یک قاب با نمایه‌سازی افزایشی “مسطح” کنید، می‌توانید از روش .reset_index() روی نتایج استفاده کنید:


gb = df.groupby(['year', 'continent'])
[['lifeExp', 'gdpPercap']].mean()
flat = gb.reset_index() 
print(flat.head())
|     year  continent  lifeExp    gdpPercap
| ۰   ۱۹۵۲  Africa     39.135500   1252.572466
| ۱   ۱۹۵۲  Americas   53.279840   4079.062552
| ۲   ۱۹۵۲  Asia       46.314394   5195.484004
| ۳   ۱۹۵۲  Europe     64.408500   5661.057435
| ۴   ۱۹۵۲  Oceana     69.255000  10298.085650

شمارش فرکانس گروهی

کار دیگری که ما اغلب با داده‌ها انجام می‌دهیم، محاسبه فرکانس‌ها است. روش‌های nunique و value_counts را می‌توان برای دریافت مقادیر منحصربه‌فرد در یک سری و فرکانس‌های آنها استفاده کرد. به عنوان مثال، در اینجا چگونگی پیدا کردن چند کشور در هر قاره آمده است:


print(df.groupby('continent')['country'].nunique()) 
continent
Africa    52
Americas  25
Asia      33
Europe    30
Oceana     2

طرح اولیه با پانداها و Matplotlib

بیشتر اوقات، وقتی می‌خواهید داده‌ها را تجسم کنید، از کتابخانه دیگری مانند Matplotlib برای تولید آن گرافیک‌ها استفاده می‌کنید. با این حال، می‌توانید مستقیماً از Matplotlib (همراه با برخی از کتابخانه‌های ترسیم‌کننده دیگر) برای ایجاد تجسم از درون پانداها استفاده کنید.

برای استفاده از پسوند ساده Matplotlib برای پانداها، ابتدا مطمئن شوید Matplotlib را با pip install matplotlib نصب کرده اید.

حالا بیایید دوباره به امید به زندگی سالانه جمعیت جهان نگاه کنیم:


global_yearly_life_expectancy = df.groupby('year')['lifeExp'].mean() 
print(global_yearly_life_expectancy) 
| year
| ۱۹۵۲  ۴۹.۰۵۷۶۲۰
| ۱۹۵۷  ۵۱.۵۰۷۴۰۱
| ۱۹۶۲  ۵۳.۶۰۹۲۴۹
| ۱۹۶۷  ۵۵.۶۷۸۲۹۰
| ۱۹۷۲  ۵۷.۶۴۷۳۸۶
| ۱۹۷۷  ۵۹.۵۷۰۱۵۷
| ۱۹۸۲  ۶۱.۵۳۳۱۹۷
| ۱۹۸۷  ۶۳.۲۱۲۶۱۳
| ۱۹۹۲  ۶۴.۱۶۰۳۳۸
| ۱۹۹۷  ۶۵.۰۱۴۶۷۶
| ۲۰۰۲  ۶۵.۶۹۴۹۲۳
| ۲۰۰۷  ۶۷.۰۰۷۴۲۳
| Name: lifeExp, dtype: float64

برای ایجاد یک نمودار اساسی از این، از:

استفاده کنید


import matplotlib.pyplot as plt
global_yearly_life_expectancy = df.groupby('year')['lifeExp'].mean() 
c = global_yearly_life_expectancy.plot().get_figure()
plt.savefig("output.png")

نمودار در فایلی در فهرست کاری فعلی به عنوان output.png ذخیره می شود. محورها و سایر برچسب‌ها روی نمودار همگی می‌توانند به صورت دستی تنظیم شوند، اما برای صادرات سریع، این روش به خوبی کار می‌کند.

نتیجه گیری

پایتون و پانداها ویژگی‌های زیادی را ارائه می‌کنند که نمی‌توانید آنها را به تنهایی از صفحات گسترده دریافت کنید. اول، آنها به شما اجازه می دهند کار خود را با داده ها خودکار کنید و نتایج را تکرارپذیر کنید. به‌جای نوشتن ماکروهای صفحه‌گسترده، که ناهموار و محدود هستند، می‌توانید از پانداها برای تجزیه و تحلیل، بخش‌بندی و تبدیل داده‌ها استفاده کنید – و از قدرت بیانی پایتون و اکوسیستم بسته (مثلاً برای ترسیم نمودار یا ارائه داده‌ها به فرمت‌های دیگر) برای انجام کارهای بیشتر استفاده کنید. بیشتر از آنچه که تنها با پانداها می توانید انجام دهید.