diff --git a/Machine Learning/ch3.pandas/pandas_book_readers/book_readers.ipynb b/Machine Learning/ch3.pandas/pandas_book_readers/book_readers.ipynb
new file mode 100644
index 0000000..ab0ea03
--- /dev/null
+++ b/Machine Learning/ch3.pandas/pandas_book_readers/book_readers.ipynb
@@ -0,0 +1,721 @@
+{
+ "cells": [
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ddU9LZWUEiAd"
+ },
+ "source": [
+ "
\n",
+ "\n",
+ "قشر کتابخوان\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "در این تمرین برای کمک به قشر کتابخوان میخواهیم به تحلیل دادههای سایت goodreads بپردازیم و اطلاعات جالب و کاربردیای را از آن استخراج کنیم.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "مجموعهداده\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "اطلاعات کتابها در فایل books_db.csv
، نویسندگان در فایل authors.csv
، ناشران در فایل publisher.csv
و زبانها در فایل language.csv
قرار گرفته است. بهکمک پانداز هرکدام از این فایلها را خوانده و در متغیر متناظر آن ذخیره کنید.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " bookID | \n",
+ " title | \n",
+ " average_rating | \n",
+ " isbn | \n",
+ " isbn13 | \n",
+ " num_pages | \n",
+ " ratings_count | \n",
+ " text_reviews_count | \n",
+ " publication_date | \n",
+ " author_id | \n",
+ " lang_id | \n",
+ " publisher_id | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 1 | \n",
+ " Harry Potter and the Half-Blood Prince (Harry ... | \n",
+ " 4.57 | \n",
+ " 439785960 | \n",
+ " 9.780440e+12 | \n",
+ " 652 | \n",
+ " 2095690 | \n",
+ " 27591 | \n",
+ " 9/16/2006 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 2 | \n",
+ " Harry Potter and the Order of the Phoenix (Har... | \n",
+ " 4.49 | \n",
+ " 439358078 | \n",
+ " 9.780440e+12 | \n",
+ " 870 | \n",
+ " 2153167 | \n",
+ " 29221 | \n",
+ " 9/1/2004 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 4 | \n",
+ " Harry Potter and the Chamber of Secrets (Harry... | \n",
+ " 4.42 | \n",
+ " 439554896 | \n",
+ " 9.780440e+12 | \n",
+ " 352 | \n",
+ " 6333 | \n",
+ " 244 | \n",
+ " 11/1/2003 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 5 | \n",
+ " Harry Potter and the Prisoner of Azkaban (Harr... | \n",
+ " 4.56 | \n",
+ " 043965548X | \n",
+ " 9.780440e+12 | \n",
+ " 435 | \n",
+ " 2339585 | \n",
+ " 36325 | \n",
+ " 5/1/2004 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 8 | \n",
+ " Harry Potter Boxed Set Books 1-5 (Harry Potte... | \n",
+ " 4.78 | \n",
+ " 439682584 | \n",
+ " 9.780440e+12 | \n",
+ " 2690 | \n",
+ " 41428 | \n",
+ " 164 | \n",
+ " 9/13/2004 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " bookID title average_rating \\\n",
+ "0 1 Harry Potter and the Half-Blood Prince (Harry ... 4.57 \n",
+ "1 2 Harry Potter and the Order of the Phoenix (Har... 4.49 \n",
+ "2 4 Harry Potter and the Chamber of Secrets (Harry... 4.42 \n",
+ "3 5 Harry Potter and the Prisoner of Azkaban (Harr... 4.56 \n",
+ "4 8 Harry Potter Boxed Set Books 1-5 (Harry Potte... 4.78 \n",
+ "\n",
+ " isbn isbn13 num_pages ratings_count text_reviews_count \\\n",
+ "0 439785960 9.780440e+12 652 2095690 27591 \n",
+ "1 439358078 9.780440e+12 870 2153167 29221 \n",
+ "2 439554896 9.780440e+12 352 6333 244 \n",
+ "3 043965548X 9.780440e+12 435 2339585 36325 \n",
+ "4 439682584 9.780440e+12 2690 41428 164 \n",
+ "\n",
+ " publication_date author_id lang_id publisher_id \n",
+ "0 9/16/2006 0 0 0 \n",
+ "1 9/1/2004 0 0 0 \n",
+ "2 11/1/2003 0 0 1 \n",
+ "3 5/1/2004 0 0 0 \n",
+ "4 9/13/2004 0 0 1 "
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "\n",
+ "df = pd.read_csv(\"./books_db.csv\")\n",
+ "authors = pd.read_csv(\"./authors.csv\")\n",
+ "language = pd.read_csv(\"./language.csv\")\n",
+ "publisher = pd.read_csv(\"./publisher.csv\")\n",
+ "\n",
+ "df.head()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت اول\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "همانطور که مشاهده میکنید در مجموعهدادهی اصلی (کتابها)، مقادیر سه ستون lang_id
، author_id
و publisher_id
تنها بهصورت آیدی (id
) هستند. این آیدیها با شمارهی نمایهها در سایر دیتافریمها متناظر هستند. در این قسمت قصد داریم تا طبق این نمایهها، اطلاعات کاملشان را از دیتافریم مربوطه استخراج کرده و به دیتافریم df
اضافه کنیم. بنابراین سه دیتافریم authors
، language
و publisher
را بهشکل مناسبی با دیتافریم df
ادغام (merge
) کنید.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " bookID | \n",
+ " title | \n",
+ " average_rating | \n",
+ " isbn | \n",
+ " isbn13 | \n",
+ " num_pages | \n",
+ " ratings_count | \n",
+ " text_reviews_count | \n",
+ " publication_date | \n",
+ " author_id | \n",
+ " lang_id | \n",
+ " publisher_id | \n",
+ " name_x | \n",
+ " code | \n",
+ " name_y | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 1 | \n",
+ " Harry Potter and the Half-Blood Prince (Harry ... | \n",
+ " 4.57 | \n",
+ " 439785960 | \n",
+ " 9.780440e+12 | \n",
+ " 652 | \n",
+ " 2095690 | \n",
+ " 27591 | \n",
+ " 9/16/2006 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " J.K. Rowling | \n",
+ " eng | \n",
+ " Scholastic Inc. | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 2 | \n",
+ " Harry Potter and the Order of the Phoenix (Har... | \n",
+ " 4.49 | \n",
+ " 439358078 | \n",
+ " 9.780440e+12 | \n",
+ " 870 | \n",
+ " 2153167 | \n",
+ " 29221 | \n",
+ " 9/1/2004 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " J.K. Rowling | \n",
+ " eng | \n",
+ " Scholastic Inc. | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 5 | \n",
+ " Harry Potter and the Prisoner of Azkaban (Harr... | \n",
+ " 4.56 | \n",
+ " 043965548X | \n",
+ " 9.780440e+12 | \n",
+ " 435 | \n",
+ " 2339585 | \n",
+ " 36325 | \n",
+ " 5/1/2004 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " J.K. Rowling | \n",
+ " eng | \n",
+ " Scholastic Inc. | \n",
+ "
\n",
+ " \n",
+ " 2837 | \n",
+ " 10546 | \n",
+ " The Long-Lost Map (Ulysses Moore #2) | \n",
+ " 4.00 | \n",
+ " 043977439X | \n",
+ " 9.780440e+12 | \n",
+ " 272 | \n",
+ " 1693 | \n",
+ " 76 | \n",
+ " 7/1/2006 | \n",
+ " 1280 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " Pierdomenico Baccalario | \n",
+ " eng | \n",
+ " Scholastic Inc. | \n",
+ "
\n",
+ " \n",
+ " 6190 | \n",
+ " 23300 | \n",
+ " The Door to Time (Ulysses Moore #1) | \n",
+ " 3.93 | \n",
+ " 439774381 | \n",
+ " 9.780440e+12 | \n",
+ " 239 | \n",
+ " 3099 | \n",
+ " 241 | \n",
+ " 1/1/2006 | \n",
+ " 1280 | \n",
+ " 0 | \n",
+ " 0 | \n",
+ " Pierdomenico Baccalario | \n",
+ " eng | \n",
+ " Scholastic Inc. | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " bookID title \\\n",
+ "0 1 Harry Potter and the Half-Blood Prince (Harry ... \n",
+ "1 2 Harry Potter and the Order of the Phoenix (Har... \n",
+ "3 5 Harry Potter and the Prisoner of Azkaban (Harr... \n",
+ "2837 10546 The Long-Lost Map (Ulysses Moore #2) \n",
+ "6190 23300 The Door to Time (Ulysses Moore #1) \n",
+ "\n",
+ " average_rating isbn isbn13 num_pages ratings_count \\\n",
+ "0 4.57 439785960 9.780440e+12 652 2095690 \n",
+ "1 4.49 439358078 9.780440e+12 870 2153167 \n",
+ "3 4.56 043965548X 9.780440e+12 435 2339585 \n",
+ "2837 4.00 043977439X 9.780440e+12 272 1693 \n",
+ "6190 3.93 439774381 9.780440e+12 239 3099 \n",
+ "\n",
+ " text_reviews_count publication_date author_id lang_id publisher_id \\\n",
+ "0 27591 9/16/2006 0 0 0 \n",
+ "1 29221 9/1/2004 0 0 0 \n",
+ "3 36325 5/1/2004 0 0 0 \n",
+ "2837 76 7/1/2006 1280 0 0 \n",
+ "6190 241 1/1/2006 1280 0 0 \n",
+ "\n",
+ " name_x code name_y \n",
+ "0 J.K. Rowling eng Scholastic Inc. \n",
+ "1 J.K. Rowling eng Scholastic Inc. \n",
+ "3 J.K. Rowling eng Scholastic Inc. \n",
+ "2837 Pierdomenico Baccalario eng Scholastic Inc. \n",
+ "6190 Pierdomenico Baccalario eng Scholastic Inc. "
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df = pd.merge(df,authors,left_on=\"author_id\",right_index=True)\n",
+ "df = pd.merge(df,language,left_on=\"lang_id\",right_index=True)\n",
+ "df = pd.merge(df,publisher,left_on=\"publisher_id\",right_index=True)\n",
+ "df.head()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "حال که تمام مقادیر اضافه شدهاند، نیازی به سه ستون id
که بهعنوان کلید استفاده کردیم نداریم. پس آنها را با استفاده از دستور drop
حذف میکنیم.\n",
+ " در درسنامههای بعدی نحوهی کار با این دستور را یاد خواهید گرفت. \n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df.drop(columns = ['author_id', 'lang_id', 'publisher_id'], inplace = True)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت دوم\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "حال نام ستونهای دیتافریم را بهگونهای تغییر دهید که بهترتیب از چپ به راست برابر نامهای زیر باشد:\n",
+ "\n",
+ "bookID
\n",
+ "title
\n",
+ "average_rating
\n",
+ "isbn
\n",
+ "isbn13
\n",
+ "num_pages
\n",
+ "ratings_count
\n",
+ "text_reviews_count
\n",
+ "publication_date
\n",
+ "author
\n",
+ "lang
\n",
+ "publisher
\n",
+ "
\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df.columns=[\"bookID\",\"title\",\"average_rating\",\"isbn\",\"isbn13\",\"num_pages\",\"ratings_count\",\"text_reviews_count\",\"publication_date\",\"author\",\"lang\",\"publisher\"]"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت سوم\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "اکنون میانگین امتیاز کتابهای هر انتشاراتی را محاسبه کرده و حاصل را در متغیر publisher_rating
ذخیره کنید.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "publisher\n",
+ "18-Oct 3.650000\n",
+ "1st Book Library 3.580000\n",
+ "1st World Library 4.180000\n",
+ "A & C Black (Childrens books) 4.400000\n",
+ "A Harvest Book/Harcourt Inc. 4.070000\n",
+ " ... \n",
+ "聯經出版事業股份有限公司 4.400000\n",
+ "英文漢聲出版股份有限公司 4.220000\n",
+ "角川書店 (Kadokawa Shoten) 3.815000\n",
+ "講談社 4.283333\n",
+ "集英社 4.237500\n",
+ "Name: average_rating, Length: 2290, dtype: float64"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "publisher_rating = df.groupby(\"publisher\").average_rating.mean()\n",
+ "publisher_rating"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت چهارم\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "در این قسمت ابتدا ستونی با نام num_pages_grp
به دیتافریم اضافه کنید که در آن تعداد صفحات کتاب را بهصورت بازههای زیر نشان دهد:\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "| مقدار | توضیح |\n",
+ "| :---: | :---: | \n",
+ "| <250
| کمتر از ۲۵۰ صفحه |\n",
+ "| 250-499
| از ۲۵۰ تا ۴۹۹ صفحه |\n",
+ "| 500-749
| از ۵۰۰ تا ۷۴۹ صفحه |\n",
+ "| 750-999
| از ۷۵۰ تا ۹۹۹ صفحه |\n",
+ "| >=1000
| بیشتر یا مساوی ۱۰۰۰ صفحه |\n",
+ "\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "راهنمایی :\n",
+ " برای این کار میتوانید از تابع np.select
استفاده کنید. \n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df['num_pages_grp'] = np.select([df.num_pages>=1000,df.num_pages>=750,df.num_pages>=500,df.num_pages>=250,df.num_pages<250],[\">=1000\",\"750-999\",\"500-749\",\"250-499\",\"<250\"])"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "\n",
+ "حال میخواهیم بدانیم هر نویسنده چند کتاب در هرکدام از این بازهها نوشته است. یعنی حاصل باید چیزی شبیه به جدول زیر باشد:\n",
+ "\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "raw",
+ "metadata": {},
+ "source": [
+ "A.B. Yehoshua 250-499 1\n",
+ " 500-749 1\n",
+ "A.D.P. Briggs 250-499 1\n",
+ "A.E. Cunningham <250 1\n",
+ "A.J. Jacobs 250-499 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "author num_pages_grp\n",
+ "A.B. Yehoshua 250-499 1\n",
+ " 500-749 1\n",
+ "A.D.P. Briggs 250-499 1\n",
+ "A.E. Cunningham <250 1\n",
+ "A.J. Jacobs 250-499 1\n",
+ " ..\n",
+ "bell hooks <250 5\n",
+ "Åsne Seierstad 250-499 3\n",
+ "Émile Zola 250-499 6\n",
+ " 500-749 3\n",
+ "Éric-Emmanuel Schmitt <250 1\n",
+ "Length: 5547, dtype: int64"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "author_page = df.groupby([\"author\",\"num_pages_grp\"]).size()\n",
+ "author_page"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "سلول جوابساز\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " برای ساختهشدن فایل result.zip
سلول زیر را اجرا کنید. توجه داشته باشید که پیش از اجرای سلول زیر تغییرات اعمال شده در نتبوک را ذخیره کرده باشید (ctrl+s
) تا در صورت نیاز به پشتیبانی امکان بررسی کد شما وجود داشته باشد.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "File Paths:\n",
+ "['books_result.csv', 'publisher_rating.csv', 'author_page.csv', 'book_readers.ipynb']\n"
+ ]
+ }
+ ],
+ "source": [
+ "import zlib\n",
+ "import zipfile\n",
+ "\n",
+ "df.to_csv('books_result.csv', index=False)\n",
+ "publisher_rating.to_csv('publisher_rating.csv', index=True)\n",
+ "author_page.to_csv(\"author_page.csv\", index=True)\n",
+ "\n",
+ "def compress(file_names):\n",
+ " print(\"File Paths:\")\n",
+ " print(file_names)\n",
+ " compression = zipfile.ZIP_DEFLATED\n",
+ " with zipfile.ZipFile(\"result.zip\", mode=\"w\") as zf:\n",
+ " for file_name in file_names:\n",
+ " zf.write('./' + file_name, file_name, compress_type=compression)\n",
+ "\n",
+ "file_names = [\"books_result.csv\", \"publisher_rating.csv\", \"author_page.csv\", \"book_readers.ipynb\"]\n",
+ "compress(file_names)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "YWBTRJvqdG_u"
+ },
+ "source": [
+ "\n",
+ "
\n",
+ "\n",
+ "\t\n",
+ "
"
+ ]
+ }
+ ],
+ "metadata": {
+ "colab": {
+ "collapsed_sections": [],
+ "name": "exercise1.ipynb",
+ "provenance": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.1"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "44e7e1b8fa2096bd5707ed7fd18b1724a2db25f4c565a7673f8b6e7bfc49d25d"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/Machine Learning/ch3.pandas/pandas_diamond/diamond.ipynb b/Machine Learning/ch3.pandas/pandas_diamond/diamond.ipynb
new file mode 100644
index 0000000..60b1990
--- /dev/null
+++ b/Machine Learning/ch3.pandas/pandas_diamond/diamond.ipynb
@@ -0,0 +1,410 @@
+{
+ "cells": [
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "الماس\n",
+ "\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "در این مسئله از دادههای یک فروشگاه الماس که شامل اطلاعات مختلف الماسها (وزن به قیراط، طول، عرض، ارتفاع و غیره) است استفاده خواهیم کرد و ساخت دیتاسری و دیتافریم پانداز را با همدیگر تمرین خواهیم کرد.\n",
+ "\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت اول:\n",
+ "برش ایدهآل\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "برای بررسی کیفیت برش الماسها از یک کارشناس کمک خواستیم و او کیفیت هر الماس را در یک لیست نوشته و لیست نهایی زیر را به ما تحویل داده است:\n",
+ " \n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "cut = ['Ideal', 'Premium', 'Premium', 'Premium', 'Premium', 'Very Good',\n",
+ " 'Premium', 'Premium', 'Ideal', 'Premium', 'Good', 'Good', 'Premium', \n",
+ " 'Very Good', 'Very Good', 'Good', 'Good','Very Good', 'Good', 'Good', \n",
+ " 'Premium', 'Premium', 'Good', 'Good']"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "با استفاده از این اطلاعات، یک دیتاسری به نام cut_series
بسازید. \n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "cut_series = pd.Series(cut)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "در دیتاسری cut_series
، کیفیت برش هر الماس ذخیره شده است. حال تعداد هر کیفیت برش را بهشکل صعودی در یک دیتاسری جدید به نام cut_sorted
ذخیره کنید. یعنی عنوان و تعداد کم تعدادترین نوع برش، باید در ابتدای این دیتاسری قرار بگیرد.\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "راهنمایی:\n",
+ "برای ساخت این دیتاسری، باید از یکی از توابع معرفیشده در درسنامهی «بررسی دیتافریم» استفاده کنید.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "Ideal 2\n",
+ "Very Good 4\n",
+ "Good 8\n",
+ "Premium 10\n",
+ "Name: count, dtype: int64"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "cut_sorted = pd.value_counts(cut_series,True,True)\n",
+ "cut_sorted"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت دوم:\n",
+ "قیراط الماسها\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ " با استفاده از ترازو الماسها را وزن کرده و حاصل را در لیست زیر قرار دادهایم.\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "carat = [1.07, 1.19, 1.19, 1.2, 1.2, 1.25, 1.2, 1.2, 1.2,\n",
+ " 1.14, 1.01, 1.01, 1.01, 1.02, 1.01, 1.01, 1.01, \n",
+ " 1.01, 1.01, 1.01, 1.01, 1.01, 1.0, 1.0]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "با استفاده از این اطلاعات، یک دیتاسری به نام carat_series
بسازید.\n",
+ "\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "carat_series = pd.Series(carat)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "در فصل نامپای با صدکها آشنا شدید. صدک هفتاد و پنجم این دیتاسری را محاسبه کنید و در متغیر carat_75
ذخیره کنید.\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "carat_75 = np.percentile( np.array(carat_series.values),75)\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت سوم:\n",
+ "ابعاد الماس\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "در این مرحله از یک کارشناس دیگر خواستیم که الماسها را اندازهگیری کند و او یک آرایهی نامپای به ما تحویل داده است.\n",
+ "
\n",
+ "یکی از راههای ذخیرهسازی آرایهی نامپای، استفاده از فرمت ذخیرهسازی npz
است. در این فایل میتوان هر تعداد آرایهی نامپای را ذخیره کرد و بعد با استفاده از نام آرایهها، آرایهی مورد نظر را از فایل بیرون کشید. برای آشنایی بیشتر با این فرمت میتوانید\n",
+ " \n",
+ " این لینک\n",
+ "\n",
+ " را مطالعه کنید. \n",
+ "
\n",
+ "چون نحوهی استفاده این فایل را برای شما توضیح ندادهایم، کد خواندن این فایل و سپس بیرون کشیدن آرایهی sizes
از آن را در سلول زیر برای شما نوشتهایم. آرایهی حاصل در متغیری به نام sizes_array
ذخیره میشود. \n",
+ " \n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[6.46, 6.42, 4.09],\n",
+ " [6.87, 6.84, 4.17],\n",
+ " [6.73, 6.66, 4.2],\n",
+ " [6.77, 6.72, 4.22],\n",
+ " [6.77, 6.72, 4.22],\n",
+ " [6.86, 6.9, 4.27],\n",
+ " [6.93, 6.8, 4.24],\n",
+ " [6.86, 6.74, 4.21],\n",
+ " [6.73, 6.68, 4.24],\n",
+ " [6.76, 6.72, 4.13],\n",
+ " [6.19, 6.23, 4.05],\n",
+ " [6.48, 6.5, 3.79],\n",
+ " [6.46, 6.41, 3.94],\n",
+ " [6.34, 6.41, 4.06],\n",
+ " [6.35, 6.3, 4.0],\n",
+ " [6.35, 6.3, 4.02],\n",
+ " [6.37, 6.31, 4.05],\n",
+ " [6.39, 6.34, 4.02],\n",
+ " [6.4, 6.32, 4.05],\n",
+ " [6.58, 6.53, 3.77],\n",
+ " [6.46, 6.37, 3.92],\n",
+ " [6.44, 6.38, 3.95],\n",
+ " [6.33, 6.38, 4.01],\n",
+ " [6.27, 6.31, 3.99]], dtype=object)"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "\n",
+ "sizes = np.load('sizes.npz', allow_pickle=True)\n",
+ "sizes_array = sizes['sizes']\n",
+ "sizes_array"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "\n",
+ " آرایهی sizes_array
دارای سه ستون است. در ستون اول طول، در ستون دوم عرض و در ستون سوم ارتفاع الماسها ذخیره شده است. \n",
+ "
\n",
+ "با استفاده از این آرایه، یک دیتافریم به نام sizes_df
بسازید و نام ستونهای آن را برابر x
, y
, z
قرار دهید. (اولین ستون x
نام دارد).\n",
+ " \n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sizes_df = pd.DataFrame(sizes_array,columns=['x','y','z'])"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت چهارم:\n",
+ "نمایهسازی\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ " برخلاف دنیای برنامهنویسان در کسبوکار الماس مرسوم نیست که شمارهگذاری از 0
شروع شود. بنابراین نمایهها را طوری تغییر دهید که از 1
شروع شوند. \n",
+ "دیتافریم جدید را در sizes_new_index
ذخیره کنید.\n",
+ "
\n",
+ "\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sizes_new_index = sizes_df.copy()\n",
+ "sizes_new_index = sizes_new_index.set_index(pd.RangeIndex(start=1, stop=25, step=1))"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "سلول جوابساز\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " برای ساختهشدن فایل result.zip
سلول زیر را اجرا کنید. توجه داشته باشید که پیش از اجرای سلول زیر تغییرات اعمال شده در نتبوک را ذخیره کرده باشید (ctrl+s
) تا در صورت نیاز به پشتیبانی امکان بررسی کد شما وجود داشته باشد.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "File Paths:\n",
+ "['cut_series.csv', 'cut_sorted.csv', 'carat_series.csv', 'carat_75', 'sizes_df.csv', 'sizes_new_index.csv', 'diamond.ipynb']\n"
+ ]
+ }
+ ],
+ "source": [
+ "import zipfile\n",
+ "import joblib\n",
+ "\n",
+ "carat_series.to_csv(\"carat_series.csv\")\n",
+ "cut_sorted.to_csv(\"cut_sorted.csv\")\n",
+ "cut_sorted.to_csv(\"cut_series.csv\")\n",
+ "joblib.dump(carat_75,\"carat_75\")\n",
+ "sizes_df.to_csv(\"sizes_df.csv\",index = True)\n",
+ "sizes_df.to_csv(\"sizes_new_index.csv\",index = True)\n",
+ " \n",
+ "def compress(file_names):\n",
+ " print(\"File Paths:\")\n",
+ " print(file_names)\n",
+ " compression = zipfile.ZIP_DEFLATED\n",
+ " with zipfile.ZipFile(\"result.zip\", mode=\"w\") as zf:\n",
+ " for file_name in file_names:\n",
+ " zf.write('./' + file_name, file_name, compress_type=compression)\n",
+ "\n",
+ "file_names = [\"cut_series.csv\", \"cut_sorted.csv\", \"carat_series.csv\",\n",
+ " \"carat_75\", \"sizes_df.csv\", \"sizes_new_index.csv\", \"diamond.ipynb\"]\n",
+ "compress(file_names)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.1"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "44e7e1b8fa2096bd5707ed7fd18b1724a2db25f4c565a7673f8b6e7bfc49d25d"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/Machine Learning/ch3.pandas/pandas_hindustan/hindustan.ipynb b/Machine Learning/ch3.pandas/pandas_hindustan/hindustan.ipynb
new file mode 100644
index 0000000..4116b8b
--- /dev/null
+++ b/Machine Learning/ch3.pandas/pandas_hindustan/hindustan.ipynb
@@ -0,0 +1,224 @@
+{
+ "cells": [
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "ff54573a",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "هندوستان\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "در این تمرین بهسراغ یک مجموعهداده از غذاهای هندوستان میرویم و بررسی میکنیم که هندوها تا چه حد ذائقهی تندی دارند. همچنین چند مورد از دیرپزترین غذاهایشان را مییابیم.\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "f7cd7632",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "مجموعهداده\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "دادههای مرتبط با این تمرین در فایل food.csv
قرار گرفته و شامل ستونهای زیر است:\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " \n",
+ "| ستون | توضیح |\n",
+ "| :---: | :---: |\n",
+ "| name
| نام غذا |\n",
+ "| ingredients
| مواد تشکیلدهندهی غذا|\n",
+ "| diet
|دارای دو مقدار vegetarian
و non vegetarian
است که نشان میدهد آیا غذا مناسب گیاهخواران هست یا خیر.|\n",
+ "| prep_time
| زمانی که طول میکشد تا غذا آماده شود. این زمان شامل زمان پخت نمیشود. مثلاً زمان پوست کندن یا شستن مواد اولیه در این ستون لحاظ شدهاند.|\n",
+ "| cook_time
| زمان پخت یک غذا| \n",
+ "| flavor_profile
| مزهی غذا را نشان میدهد. دارای ۴ مقدار spicy
برای غذاهای تند، sweet
برای غذاهای شیرین، bitter
برای غذاهای تلخ و sour
برای غذاهای ترش است.|\n",
+ "| course
| وعدهی اصلی، میانوعده، دسر یا پیشغذا بودن یک غذا را نشان میدهد.|\n",
+ "| state
| ایالتی که زادگاه غذاست یا حداقل این غذا در آنجا معروف است.|\n",
+ "| region
| منطقهای که ایالت (state
) در آن واقع شده است.|\n",
+ "\n",
+ "\n",
+ "\n",
+ "
\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "1d2bc674",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd \n",
+ "import numpy as np"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "cf5dff88",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df = pd.read_csv(\"./food.csv\")"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "067c1145",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت اول\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "بسیار شنیدهایم که هندوها عاشق غذاهای تند هستند! حال میخواهیم با توجه به مجموعهدادهی موجود صحت این گزاره را بررسی کرده و ببینیم که چه نسبتی از کل غذاهای این مجموعه، دارای مزهی تندی هستند؟\n",
+ "برای این کار کافیست حاصل تقسیم تعداد غذاهای تند مزه را بر تعداد کل غذاها حساب کنید و در متغیر spicy_ratio
ذخیره کنید.\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "d6461854",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "spicy_ratio = df[df.flavor_profile==\"spicy\"].shape[0]/df.shape[0]"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "5137d5bc",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت دوم\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "اکنون میخواهیم بدانیم کدام غذاها از لحظهی شروع آمادهسازی مخلفات تا لحظهی آمادهی سرو شدن، بیشترین زمان را مصرف میکنند.\n",
+ "برای اینکار باید جمع مدت زمان آمادهسازی و زمان لازم برای طبخ غذا را در نظر گرفته و سپس ۱۰ غذایی که بیشترین زمان را مصرف میکنند بهترتیب نزولی در قالب یک دیتافریم در متغیر df_most_time_consuming
ذخیره کنید. \n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "نکته:\n",
+ " فرمت و ترتیب ستونهای دیتافریم df_most_time_consuming
باید دقیقاً شبیه به دیتافریم df
باشد. یعنی این دیتافریم دارای ۱۰ سطر و ۹ ستون خواهد بود.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "ae1f814c",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df[\"consuming_time\"]=df.apply(lambda row : row['prep_time'] + row['cook_time'], axis=1 )\n",
+ "df_most_time_consuming = df.sort_values(by='consuming_time' , ascending=False)[0:10]\n",
+ "df.drop(\"consuming_time\" , axis=1,inplace=True)\n",
+ "df_most_time_consuming.drop(\"consuming_time\" , axis=1,inplace=True)\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "7341ff2d",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "سلول جوابساز\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "5f63b15c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "File Paths:\n",
+ "['spicy_ratio.npy', 'df_most_time_consuming.csv', 'hindustan.ipynb']\n"
+ ]
+ }
+ ],
+ "source": [
+ "import zipfile\n",
+ "\n",
+ "np.save(\"spicy_ratio\", np.array(spicy_ratio))\n",
+ "df_most_time_consuming.to_csv('df_most_time_consuming.csv', index=False)\n",
+ "\n",
+ "def compress(file_names):\n",
+ " print(\"File Paths:\")\n",
+ " print(file_names)\n",
+ " compression = zipfile.ZIP_DEFLATED\n",
+ " with zipfile.ZipFile(\"result.zip\", mode=\"w\") as zf:\n",
+ " for file_name in file_names:\n",
+ " zf.write('./' + file_name, file_name, compress_type=compression)\n",
+ "\n",
+ "file_names = [\"spicy_ratio.npy\", \"df_most_time_consuming.csv\", \"hindustan.ipynb\"]\n",
+ "compress(file_names)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.1"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "44e7e1b8fa2096bd5707ed7fd18b1724a2db25f4c565a7673f8b6e7bfc49d25d"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/Machine Learning/ch3.pandas/pandas_mad_cyclists/mad_cyclists.ipynb b/Machine Learning/ch3.pandas/pandas_mad_cyclists/mad_cyclists.ipynb
new file mode 100644
index 0000000..6c06e73
--- /dev/null
+++ b/Machine Learning/ch3.pandas/pandas_mad_cyclists/mad_cyclists.ipynb
@@ -0,0 +1,1141 @@
+{
+ "cells": [
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "دوچرخهسواران بیطاقت\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "دوچرخهسوران خیلی روی دما حساس هستند. دمایی که دوچرخهسواران احساس میکنند معمولاً با سرعت باد و رطوبت هوا رابطهی مستقیم دارد. در این تمرین میخواهیم با توجه به مجموعهدادهی دمای روزهای مختلف، به یک کسبوکار اجارهی دوچرخه کمک کنیم تا در روزهای مختلف و در دماهای مختلف دوچرخههای بیشتری اجاره دهد. \n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "مجموعهداده\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "با اجرای سلول زیر میتوانید دادههای این تمرین را بهشکل یک دیتافریم بخوانید. این مجموعهداده شامل ستونهای زیر است:\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "| شماره گروه | توضیحات |\n",
+ "| :---: | :---: | \n",
+ "| cnt
| تعداد دوچرخههای اجاره دادهشده در روز |\n",
+ "| t1
| دمای واقعی اندازهگیریشده در آن روز |\n",
+ "| t2
| میانگین دمایی که دوچرخهسواران احساس کردهاند |\n",
+ "| humidity
| رطوبت هوا در آن روز |\n",
+ "| wind_speed
| سرعت باد در آن روز |\n",
+ "| is_weekend
| آیا آن روز، روز غیرکاری (آخر هفته) هست یا خیر |\n",
+ "| season
| چندمین فصل سال |\n",
+ "\n",
+ "\n",
+ "
\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " cnt | \n",
+ " t1 | \n",
+ " t2 | \n",
+ " humidity | \n",
+ " wind_speed | \n",
+ " is_weekend | \n",
+ " season | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 182 | \n",
+ " 3.0 | \n",
+ " 2.0 | \n",
+ " 93.0 | \n",
+ " 6.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 138 | \n",
+ " 3.0 | \n",
+ " 2.5 | \n",
+ " 93.0 | \n",
+ " 5.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 134 | \n",
+ " 2.5 | \n",
+ " 2.5 | \n",
+ " 96.5 | \n",
+ " 0.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 72 | \n",
+ " 2.0 | \n",
+ " 2.0 | \n",
+ " 100.0 | \n",
+ " 0.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 47 | \n",
+ " 2.0 | \n",
+ " 0.0 | \n",
+ " 93.0 | \n",
+ " 6.5 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " cnt t1 t2 humidity wind_speed is_weekend season\n",
+ "0 182 3.0 2.0 93.0 6.0 1.0 3.0\n",
+ "1 138 3.0 2.5 93.0 5.0 1.0 3.0\n",
+ "2 134 2.5 2.5 96.5 0.0 1.0 3.0\n",
+ "3 72 2.0 2.0 100.0 0.0 1.0 3.0\n",
+ "4 47 2.0 0.0 93.0 6.5 1.0 3.0"
+ ]
+ },
+ "execution_count": 1,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "from numpy import nan as NA\n",
+ "\n",
+ "df = pd.read_csv('bikes_borrowed.csv')\n",
+ "df.head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " نحوهی کار با تابع read_csv
را در درسنامههای آینده یاد میگیرید؛ اما به استفاده از head
در این کد دقت کنید؛ همانطور که گفتیم، این تابع بهطور پیشفرض، ۵ دادهی بالای دیتافریم را به ما نشان میدهد.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت اول\n",
+ " \n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " همانطور که میبینید نام ستونهای t1
و t2
خیلی کلی است و بیانگر معنای مقدار آنها نیست، به همین دلیل خوب است تا نام آنها را تغییر دهیم.\n",
+ "
\n",
+ " در سلول زیر، نام ستون t1
را به t_real
و نام ستون t2
را به t_feels_like
تغییر دهید.\n",
+ "
\n",
+ " برای تغییر نام نمایهها یا ستونها میتوانیم همچون کد زیر از تابع rename
استفاده کنیم:\n",
+ "
\n",
+ "\n",
+ "
\n",
+ "\n",
+ "`df.rename(columns={\"col1\": \"new_col1\", \"col2\": \"new_col2\"} , inplace = True)`\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " cnt | \n",
+ " t_real | \n",
+ " t_feels_like | \n",
+ " humidity | \n",
+ " wind_speed | \n",
+ " is_weekend | \n",
+ " season | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " 182 | \n",
+ " 3.0 | \n",
+ " 2.0 | \n",
+ " 93.0 | \n",
+ " 6.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " 138 | \n",
+ " 3.0 | \n",
+ " 2.5 | \n",
+ " 93.0 | \n",
+ " 5.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " 134 | \n",
+ " 2.5 | \n",
+ " 2.5 | \n",
+ " 96.5 | \n",
+ " 0.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " 72 | \n",
+ " 2.0 | \n",
+ " 2.0 | \n",
+ " 100.0 | \n",
+ " 0.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " 47 | \n",
+ " 2.0 | \n",
+ " 0.0 | \n",
+ " 93.0 | \n",
+ " 6.5 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " cnt t_real t_feels_like humidity wind_speed is_weekend season\n",
+ "0 182 3.0 2.0 93.0 6.0 1.0 3.0\n",
+ "1 138 3.0 2.5 93.0 5.0 1.0 3.0\n",
+ "2 134 2.5 2.5 96.5 0.0 1.0 3.0\n",
+ "3 72 2.0 2.0 100.0 0.0 1.0 3.0\n",
+ "4 47 2.0 0.0 93.0 6.5 1.0 3.0"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df.rename(columns={\"t1\":\"t_real\",\"t2\":\"t_feels_like\"},inplace=True)\n",
+ "\n",
+ "df.head()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " به پارامتر inplace = True
دقت کنید؛ وجود این پارامتر باعث میشود که تابع rename
، بهجای آنکه یک کپی از دیتافریم تهیه کرده و بعد از اعمال تغییرات آن کپی را خروجی دهد، تغییرات را مستقیماً روی دیتافریم اصلی اعمال کند.\n",
+ "
\n",
+ "برای درک بهتر این موضوع میتوانید یکبار این پارامتر را حذف کرده و سپس مجدد df.head()
را خروجی بگیرید و بررسی کنید که آیا نام ستونها تغییر کرده است یا خیر؟\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت دوم\n",
+ " \n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "از آنجایی که اغلب روزهایی که دوچرخهسواران از هوا گلایه دارند روزهای بادی است، تصمیم گرفتیم که محاسبات را فقط برای روزهایی که سرعت باد بیشتر از ۱۰ است انجام دهیم.\n",
+ "
\n",
+ " بنابراین در دیتافریم windy_days_df
، تنها دادههایی را ذخیره کنید که سرعت باد آنها بیشتر از ۱۰ باشد (خود ۱۰ را در نظر نگیرید).\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " cnt | \n",
+ " t_real | \n",
+ " t_feels_like | \n",
+ " humidity | \n",
+ " wind_speed | \n",
+ " is_weekend | \n",
+ " season | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 10 | \n",
+ " 528 | \n",
+ " 3.0 | \n",
+ " -0.5 | \n",
+ " 93.0 | \n",
+ " 12.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " 727 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 100.0 | \n",
+ " 12.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " 862 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 96.5 | \n",
+ " 13.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " 916 | \n",
+ " 3.0 | \n",
+ " -0.5 | \n",
+ " 87.0 | \n",
+ " 15.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " 869 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 93.0 | \n",
+ " 11.0 | \n",
+ " 1.0 | \n",
+ " 3.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " cnt t_real t_feels_like humidity wind_speed is_weekend season\n",
+ "10 528 3.0 -0.5 93.0 12.0 1.0 3.0\n",
+ "11 727 2.0 -1.5 100.0 12.0 1.0 3.0\n",
+ "12 862 2.0 -1.5 96.5 13.0 1.0 3.0\n",
+ "13 916 3.0 -0.5 87.0 15.0 1.0 3.0\n",
+ "15 869 2.0 -1.5 93.0 11.0 1.0 3.0"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "windy_days_df = df[df[\"wind_speed\"]>10]\n",
+ "\n",
+ "windy_days_df.head()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت سوم\n",
+ " \n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "برای انجام باقی محاسبات فقط ستونهای مخصوص دما را نیاز داریم؛ پس برای دیتافریم windy_days_df
، ستونهای humidity
, t_feels_like
, t_real
و wind_speed
را ذخیره کرده و باقی ستونها را نادیده بگیرید.\n",
+ "\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " t_real | \n",
+ " t_feels_like | \n",
+ " humidity | \n",
+ " wind_speed | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 10 | \n",
+ " 3.0 | \n",
+ " -0.5 | \n",
+ " 93.0 | \n",
+ " 12.0 | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 100.0 | \n",
+ " 12.0 | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 96.5 | \n",
+ " 13.0 | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " 3.0 | \n",
+ " -0.5 | \n",
+ " 87.0 | \n",
+ " 15.0 | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 93.0 | \n",
+ " 11.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " t_real t_feels_like humidity wind_speed\n",
+ "10 3.0 -0.5 93.0 12.0\n",
+ "11 2.0 -1.5 100.0 12.0\n",
+ "12 2.0 -1.5 96.5 13.0\n",
+ "13 3.0 -0.5 87.0 15.0\n",
+ "15 2.0 -1.5 93.0 11.0"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "windy_days_df = windy_days_df[[\"t_real\",\"t_feels_like\",\"humidity\",\"wind_speed\"]]\n",
+ "\n",
+ "windy_days_df.head()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "در مراحل بعدی میخواهیم برخی مقادیر دیتافریم را تغییر دهیم پس برای آنکه دیتافریم اصلی و windy_days_df
تغییر نکنند لازم است تا از تابع copy
استفاده کنیم.\n",
+ "
\n",
+ "بهطور کلی استفاده از عملگر مساوی برای دیتافریمها در پانداز مانند نامپای عمل میکنند و تنها یک اشارهگر (pointer) جدید به همان دیتافریم اضافه میشود. بنابراین، تغییر دادن هر کدام از دیتافریمها باعث تغییر دیگری نیز میشود.\n",
+ "
\n",
+ " استفاده از تابع copy
این قابلیت را برای ما ایجاد میکند که یک کپی از دیتافریم اولیه دریافت کنیم و تغییر یکی تاثیری روی دیگری نداشته باشد.\n",
+ "
\n",
+ "در ادامه بیشتر این ویژگی را بررسی میکنیم اما فعلاً کافیست سلول زیر را اجرا کنید.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "temperature_df = windy_days_df.copy()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت چهارم\n",
+ " \n",
+ "
\n",
+ "\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "برای انجام تحلیلهای بهتر نیاز داریم بدانیم که یک روز نسبت به بازدهی کلی دما تا چهاندازه گرم است. برای این کار بهترتیب مراحل زیر را انجام دهید:\n",
+ "
\n",
+ " ۱- در متغیر t_max
مقدار ماکزیمم ستون t_real
را ذخیره کنید.\n",
+ "
\n",
+ " ۲- در متغیر t_min
مقدار مینیمم ستون t_real
را ذخیره کنید.\n",
+ "
\n",
+ "۳- ستون جدیدی به نام t_percent
به دیتافریم اضافه کنید. در این ستون از فرمول زیر برای نرمالسازی و پیدا کردن دمای نسبی استفاده کنید.\n",
+ "
\n",
+ "\n",
+ "
\n",
+ "\n",
+ "`((temp - min) / (max - min)) * 100`\n",
+ "\n",
+ "\n",
+ "\n",
+ "راهنمایی:\n",
+ " تمام عملیات این مرحله را میتوانید با توابع نامپای انجام دهید. همانطور که گفتیم پانداز بر اساس نامپای نوشته شده، پس تمامی عملیاتهای نامپای در اینجا هم قابل استفاده است.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " t_real | \n",
+ " t_feels_like | \n",
+ " humidity | \n",
+ " wind_speed | \n",
+ " t_percent | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 10 | \n",
+ " 3.0 | \n",
+ " -0.5 | \n",
+ " 93.0 | \n",
+ " 12.0 | \n",
+ " 11.428571 | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 100.0 | \n",
+ " 12.0 | \n",
+ " 8.571429 | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 96.5 | \n",
+ " 13.0 | \n",
+ " 8.571429 | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " 3.0 | \n",
+ " -0.5 | \n",
+ " 87.0 | \n",
+ " 15.0 | \n",
+ " 11.428571 | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 93.0 | \n",
+ " 11.0 | \n",
+ " 8.571429 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " t_real t_feels_like humidity wind_speed t_percent\n",
+ "10 3.0 -0.5 93.0 12.0 11.428571\n",
+ "11 2.0 -1.5 100.0 12.0 8.571429\n",
+ "12 2.0 -1.5 96.5 13.0 8.571429\n",
+ "13 3.0 -0.5 87.0 15.0 11.428571\n",
+ "15 2.0 -1.5 93.0 11.0 8.571429"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "t_max = np.max(temperature_df[\"t_real\"])\n",
+ "t_min = np.min(temperature_df[\"t_real\"])\n",
+ "temperature_df['t_percent'] = ((temperature_df[\"t_real\"] - t_min) / (t_max - t_min)) * 100\n",
+ "\n",
+ "temperature_df.head()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت پنجم\n",
+ " \n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "حال میخواهیم دمایی که احساس میشود را طبق اطلاعات موجود پیشبینی کرده و مقادیر این ستون (t_feels_like
) را جایگزین کنیم.\n",
+ "برای مقداردهی این ستون از فرمول زیر استفاده کنید:\n",
+ "
\n",
+ "\n",
+ "
\n",
+ "\n",
+ "`t_feels_like = t_real + (humidity * t_real)/1000 - (wind_speed)/10 -2`\n",
+ "
\n",
+ "\n",
+ "\n",
+ " یادآوری:\n",
+ " هر ستون دیتافریم را میتوانید مانند یک سری جدا کرده و مانند یک آرایهی نامپای با آن رفتار کنید.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " t_real | \n",
+ " t_feels_like | \n",
+ " humidity | \n",
+ " wind_speed | \n",
+ " t_percent | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 10 | \n",
+ " 3.0 | \n",
+ " 0.079 | \n",
+ " 93.0 | \n",
+ " 12.0 | \n",
+ " 11.428571 | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " 2.0 | \n",
+ " -1.000 | \n",
+ " 100.0 | \n",
+ " 12.0 | \n",
+ " 8.571429 | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " 2.0 | \n",
+ " -1.107 | \n",
+ " 96.5 | \n",
+ " 13.0 | \n",
+ " 8.571429 | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " 3.0 | \n",
+ " -0.239 | \n",
+ " 87.0 | \n",
+ " 15.0 | \n",
+ " 11.428571 | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " 2.0 | \n",
+ " -0.914 | \n",
+ " 93.0 | \n",
+ " 11.0 | \n",
+ " 8.571429 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " t_real t_feels_like humidity wind_speed t_percent\n",
+ "10 3.0 0.079 93.0 12.0 11.428571\n",
+ "11 2.0 -1.000 100.0 12.0 8.571429\n",
+ "12 2.0 -1.107 96.5 13.0 8.571429\n",
+ "13 3.0 -0.239 87.0 15.0 11.428571\n",
+ "15 2.0 -0.914 93.0 11.0 8.571429"
+ ]
+ },
+ "execution_count": 7,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "temperature_df['t_feels_like'] = df.t_real + (df.humidity * df.t_real)/1000 - (df.wind_speed)/10 -2\n",
+ "\n",
+ "temperature_df.head()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " همانطور که میبینید مقدار ستون t_feels_like
تغییر کرده و دیگر مانند آنچه در دیتافریم اولیه داشتیم نیست. حال بیایید کارکرد تابع copy
را بررسی کنیم. اگر تمام مراحل را درست پیش رفته باشید، مقدار ستون t_feels_like
در دیتافریم windy_days_df
نباید تغییر کرده باشد. برای اطمینان از این موضوع با استفاده از تابع head
میتوانیم مقادیر این دو دیتافریم را مقایسه کنیم.\n",
+ "\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " t_real | \n",
+ " t_feels_like | \n",
+ " humidity | \n",
+ " wind_speed | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 10 | \n",
+ " 3.0 | \n",
+ " -0.5 | \n",
+ " 93.0 | \n",
+ " 12.0 | \n",
+ "
\n",
+ " \n",
+ " 11 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 100.0 | \n",
+ " 12.0 | \n",
+ "
\n",
+ " \n",
+ " 12 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 96.5 | \n",
+ " 13.0 | \n",
+ "
\n",
+ " \n",
+ " 13 | \n",
+ " 3.0 | \n",
+ " -0.5 | \n",
+ " 87.0 | \n",
+ " 15.0 | \n",
+ "
\n",
+ " \n",
+ " 15 | \n",
+ " 2.0 | \n",
+ " -1.5 | \n",
+ " 93.0 | \n",
+ " 11.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " t_real t_feels_like humidity wind_speed\n",
+ "10 3.0 -0.5 93.0 12.0\n",
+ "11 2.0 -1.5 100.0 12.0\n",
+ "12 2.0 -1.5 96.5 13.0\n",
+ "13 3.0 -0.5 87.0 15.0\n",
+ "15 2.0 -1.5 93.0 11.0"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "windy_days_df.head()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت ششم\n",
+ " \n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "در نهایت میخواهیم دقت این پیشبینی را محاسبه کنیم. برای این کار از فرمول زیر استفاده میکنیم که با نام Mean Absolute Error یا MAE شناخته میشود.\n",
+ "
\n",
+ "\n",
+ "
\n",
+ "\n",
+ "`np.mean(np.abs(temperature_df['t_feels_like'] - windy_days_df['t_feels_like']))`\n",
+ "
\n",
+ "\n",
+ "\n",
+ " این مقدار را محاسبه و در متغیر diffrence
ذخیره کنید.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2.028340505491597\n"
+ ]
+ }
+ ],
+ "source": [
+ "diffrence = np.mean(np.abs(temperature_df['t_feels_like'] - windy_days_df['t_feels_like']))\n",
+ "print(diffrence)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "قسمت هفتم\n",
+ " \n",
+ "
\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " در این تمرین با تابع head(n)
کار کردیم اما بیایید به بررسی عمیقتر این تابع بپردازیم.\n",
+ "
\n",
+ "بهطور کلی این تابع تنها برای نمایش دادهها استفاده نمیشود، بلکه اعمال آن روی دیتافریم یک کپی از n
دادهی اول آن را برمیگرداند و میتوان آن را در دیتافریم جداگانهای ذخیره کرد.\n",
+ "
\n",
+ " در دیتافریم زیر، ۱۰۰ دادهی اول دیتافریم temperature_df
را ذخیره کنید.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "final_df = temperature_df.head(100)"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "سلول جوابساز\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " برای ساختهشدن فایل result.zip
سلول زیر را اجرا کنید. توجه داشته باشید که پیش از اجرای سلول زیر تغییرات اعمال شده در نتبوک را ذخیره کرده باشید (ctrl+s
) تا در صورت نیاز به پشتیبانی امکان بررسی کد شما وجود داشته باشد.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "File Paths:\n",
+ "['bikes.csv', 'windy_days.csv', 'temperature.csv', 'final.csv', 'answers.npz', 'mad_cyclists.ipynb']\n"
+ ]
+ }
+ ],
+ "source": [
+ "import zlib\n",
+ "import zipfile\n",
+ "\n",
+ "np.savez(\"answers.npz\", diffrence=diffrence, t_min=t_min , t_max=t_max)\n",
+ "df.to_csv('bikes.csv', index=True)\n",
+ "windy_days_df.to_csv('windy_days.csv', index=True)\n",
+ "temperature_df.to_csv(\"temperature.csv\", index=True)\n",
+ "final_df.to_csv(\"final.csv\", index=True)\n",
+ "\n",
+ "def compress(file_names):\n",
+ " print(\"File Paths:\")\n",
+ " print(file_names)\n",
+ " compression = zipfile.ZIP_DEFLATED\n",
+ " with zipfile.ZipFile(\"result.zip\", mode=\"w\") as zf:\n",
+ " for file_name in file_names:\n",
+ " zf.write('./' + file_name, file_name, compress_type=compression)\n",
+ "\n",
+ "file_names = [\"bikes.csv\", \"windy_days.csv\", \"temperature.csv\", \n",
+ " \"final.csv\", \"answers.npz\" , \"mad_cyclists.ipynb\"]\n",
+ "compress(file_names)"
+ ]
+ }
+ ],
+ "metadata": {
+ "colab": {
+ "collapsed_sections": [],
+ "name": "exercise1.ipynb",
+ "provenance": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.1"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "44e7e1b8fa2096bd5707ed7fd18b1724a2db25f4c565a7673f8b6e7bfc49d25d"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/Machine Learning/ch3.pandas/pandas_shakgram/shakhgram.ipynb b/Machine Learning/ch3.pandas/pandas_shakgram/shakhgram.ipynb
new file mode 100644
index 0000000..cac0131
--- /dev/null
+++ b/Machine Learning/ch3.pandas/pandas_shakgram/shakhgram.ipynb
@@ -0,0 +1,444 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "d64d01af",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " شاخگرام\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "4e177dbd-7e65-45b6-8221-1dec02f863e2",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\t\n",
+ "در درسنامههای پیشین با ساختماندادههای پرکاربرد در پانداز آشنا شدیم. در این تمرین، قصد داریم انتخاب داده از یک دیتافریم را بیشتر تمرین کنیم.\n",
+ "مجموعهدادهای که برای این تمرین در دست داریم، مربوط به یک شبکهی اجتماعی فرضی به نام شاخگرام است که در آن افراد سعی میکنند هرچه بیشتر شاخ شوند!\n",
+ " هدف اصلی این تمرین بررسی دادههای شاخگرام و نوشتن شرطهای گوناگون جهت فیلتر کردن شاخهای سطوح مختلف است.\n",
+ " \n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "3934f0cc",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "1792e7ff",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "مجموعهداده\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "دادههای مربوط به این تمرین در فایل shakhgram.csv
قرار گرفته و به کمک سلول زیر میتوانید آن را به شکل یک دیتافریم بخوانید و در متغیر df
ذخیره کنید. این دیتافریم شامل ستونهای زیر است:\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "| نام ستون | توضیحات |\n",
+ "| :---: | :---: |\n",
+ "| `owner_name` | اسم صاحب پیج |\n",
+ "| `follower` | تعداد دنبالکنندگان پیج |\n",
+ "| `following` | تعداد دنبالشوندگان پیج |\n",
+ "| `post_number` | تعداد پستهای پیج |\n",
+ "\n",
+ "\n",
+ "
\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "c5312517",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df = pd.read_csv(\"shakhgram.csv\")"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "b562fdc1-2071-47e5-8aae-eb3581aadd99",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " مشاهدهی دادهها\n",
+ " \n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "با اجرای سلول زیر، ۵ سطر اول دیتافریم نمایش داده میشود تا یک نگاه کلی به دادهها داشته باشیم.\n",
+ "پیشنهاد میکنیم سعی کنید ستونها و سطرهای مختلفی از دیتافریم را انتخاب و مشاهده کنید تا علاوه بر اینکه با مجموعهداده بیشتر آشنا میشوید، برای پیادهسازی پاسخ تمرین نیز آمادهتر شوید!\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "856f8d8c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " owner_name | \n",
+ " follower | \n",
+ " following | \n",
+ " post_number | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 | \n",
+ " Muhammad Schaefer | \n",
+ " 108751787.0 | \n",
+ " 45.0 | \n",
+ " 61.0 | \n",
+ "
\n",
+ " \n",
+ " 1 | \n",
+ " Ezra Kemp | \n",
+ " 172731383.0 | \n",
+ " 71.0 | \n",
+ " 43.0 | \n",
+ "
\n",
+ " \n",
+ " 2 | \n",
+ " Eli Good | \n",
+ " 105194939.0 | \n",
+ " 20.0 | \n",
+ " 44.0 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " Lillianna Pruitt | \n",
+ " 14807976.0 | \n",
+ " 11.0 | \n",
+ " 88.0 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " Carlie Woodward | \n",
+ " 228517005.0 | \n",
+ " 68.0 | \n",
+ " 52.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " owner_name follower following post_number\n",
+ "0 Muhammad Schaefer 108751787.0 45.0 61.0\n",
+ "1 Ezra Kemp 172731383.0 71.0 43.0\n",
+ "2 Eli Good 105194939.0 20.0 44.0\n",
+ "3 Lillianna Pruitt 14807976.0 11.0 88.0\n",
+ "4 Carlie Woodward 228517005.0 68.0 52.0"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df.head()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "aa82e222",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " قسمت اول\n",
+ " \n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ " در این شبکهی اجتماعی، ۵ دسته از شاخبودن وجود دارد. برای اینکه عضو هر دسته باشیم، میبایست پیج و اسم ما شرایط خاصی داشته باشد.\n",
+ "
\n",
+ " اولین دسته از شاخهای شاخگرام، شاخهای برنجی هستند؛ شاخهای برنجی، افرادی هستند که تعداد افرادی که توسط پیجشان دنبال میشوند (following
) از ۱۱ کمتر باشد.\n",
+ "
\n",
+ " در سلول زیر، بخشی از دیتافریم اصلی را که شرایط شاخهای برنجی دارند جدا کرده و در متغیر berenji_df
ذخیره کنید.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "f16be0eb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "berenji_df = df[df.following<11]"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "77416747",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " قسمت دوم\n",
+ " \n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ " در متغیر mesi_df
، شاخهای مسی را ذخیره کنید؛ شاخهای مسی، افرادی هستند که تعداد پستهای پیجشان از تعداد افرادی که آن پیج دنبالشان میکند (following
) بیشتر باشد.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "51f5a12b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mesi_df = df[df.following\n",
+ "\n",
+ " قسمت سوم\n",
+ " \n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " در متغیر boronzi_df
، شاخهای برنزی را ذخیره کنید؛\n",
+ " شاخهای برنزی، افرادی هستند که تعداد دنبالکنندگان (follower
) پیجشان بیشتر از یک میلیون نفر باشد.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "76184e27",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "boronzi_df = df[df.follower>1000000]"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "e8ef45c6-0367-4e24-82c0-9ab6b97a34b2",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " قسمت چهارم\n",
+ " \n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ " در متغیر noghreyee_df
، شاخهای نقرهای را ذخیره کنید؛ شاخهای نقرهای، افرادی هستند که دو شرط زیر همزمان برای آنها برقرار باشد:\n",
+ " \n",
+ " - تعداد دنبالکنندگان (
follower
) پیجشان بزرگتر یا مساوی ۱۰ میلیون باشد. \n",
+ " - تعداد دنبالشوندگان توسط پیج (
following
) کمتر از ۵۰ باشد. \n",
+ "
\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "6b8b4f92",
+ "metadata": {
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "noghreyee_df = df[(df.follower>=10000000) & (df.following<50)]"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "79b40e28-7007-48b5-95b1-bd8c3e5f05ae",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " قسمت پنجم\n",
+ " \n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ " در متغیر talayee_df
، شاخهای طلایی را ذخیره کنید؛\n",
+ "شاخهای طلایی افرادی هستند که حداقل یکی از دو شرط زیر را داشته باشند (یعنی شرط اول یا شرط دوم)\n",
+ "\n",
+ " - تعداد دنبالکنندگان (
follower
) پیجشان بزرگتر از ۱۰ میلیون و تعداد دنبالشوندگان (following
) آنها کمتر از ۲۰ باشد. \n",
+ " - تعداد پستهایشان کمتر از ۱۵ باشد و حرف
R
در اسم صاحب پیج وجود داشته باشد (مثل !BooAzaR
). \n",
+ "
\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "099d1ff4",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "talayee_df = df[((df.follower>10000000) & (df.following<20) | (df.post_number<15) & (df.owner_name.str.contains('R')))]"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "ad56a791-6354-4597-babf-c9df1c83ca73",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "سلول جوابساز\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " برای ساختهشدن فایل result.zip
سلول زیر را اجرا کنید. توجه داشته باشید که پیش از اجرای سلول زیر تغییرات اعمال شده در نتبوک را ذخیره کرده باشید (ctrl+s
) تا در صورت نیاز به پشتیبانی امکان بررسی کد شما وجود داشته باشد.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "9b01fa06",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "File Paths:\n",
+ "['berenji.csv', 'mesi.csv', 'boronzi.csv', 'noghreyee.csv', 'talayee.csv', 'shakhgram.ipynb']\n"
+ ]
+ }
+ ],
+ "source": [
+ "import zlib\n",
+ "import zipfile\n",
+ "\n",
+ "berenji_df.to_csv('berenji.csv', index=True)\n",
+ "mesi_df.to_csv('mesi.csv', index=True)\n",
+ "boronzi_df.to_csv(\"boronzi.csv\", index=True)\n",
+ "noghreyee_df.to_csv(\"noghreyee.csv\", index=True)\n",
+ "talayee_df.to_csv(\"talayee.csv\", index=True)\n",
+ "\n",
+ "def compress(file_names):\n",
+ " print(\"File Paths:\")\n",
+ " print(file_names)\n",
+ " compression = zipfile.ZIP_DEFLATED\n",
+ " with zipfile.ZipFile(\"result.zip\", mode=\"w\") as zf:\n",
+ " for file_name in file_names:\n",
+ " zf.write('./' + file_name, file_name, compress_type=compression)\n",
+ "\n",
+ "file_names = [\"berenji.csv\", \"mesi.csv\", \"boronzi.csv\",\n",
+ " \"noghreyee.csv\", \"talayee.csv\", \"shakhgram.ipynb\"]\n",
+ "compress(file_names)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.1"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "44e7e1b8fa2096bd5707ed7fd18b1724a2db25f4c565a7673f8b6e7bfc49d25d"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/Machine Learning/ch3.pandas/pandas_yektanet/yektanet.ipynb b/Machine Learning/ch3.pandas/pandas_yektanet/yektanet.ipynb
new file mode 100644
index 0000000..2bdc72a
--- /dev/null
+++ b/Machine Learning/ch3.pandas/pandas_yektanet/yektanet.ipynb
@@ -0,0 +1,591 @@
+{
+ "cells": [
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "ac1d21fa-520d-4a4c-9b26-7942fb833449",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " یکتانت\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "دادههایی که در این تمرین استفاده میکنیم، دادههایی است که شرکت یکتانت از وبسایتهای مختلف جمعآوری کرده است. قصد داریم با بررسی آمار مشاهدهی کاربران از وبسایتها، درصد شهرت وبسایتهای فارسی با کلیدواژههای پرکاربردتر را محاسبه و بررسی کنیم.\n",
+ "\n",
+ "
\n"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "e76aae32",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "مجموعهداده\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "دادههای این تمرین از طریق فایل yektanet.csv
در دسترس شما قرار گرفته است. ابتدا این فایل را خوانده و نگاهی به آن بیندازید. توضیح هرکدام از ستونهای این مجموعهداده در جدول زیر آمده است:\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "| ستون | توضیح |\n",
+ "| :---: | :---: |\n",
+ "| `keywords` | کلیدواژههایی که هر وبسایت با آنها تعریف میشود و معمولاً در جستوجوها با آن موضوع نمایش داده میشود. |\n",
+ "| `segments` | دستهبندیهایی که برای هر وبسایت در نظر میگیریم و برای تبلیغات استفاده میشوند. |\n",
+ "| `visit count` | تعداد بازدیدهای متوسط صفحه در یک روز |\n",
+ "\n",
+ "\n",
+ "
\n",
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "65ff8052",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd \n",
+ "import numpy as np"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "995dac76",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " keywords | \n",
+ " segments | \n",
+ " visit count | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 219614 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment', 'varzeshi'] | \n",
+ " 641 | \n",
+ "
\n",
+ " \n",
+ " 219615 | \n",
+ " ['زیرنویس', 'فارسی فیلم', 'دانلود زیرنویس'] | \n",
+ " ['femaleSegment'] | \n",
+ " 355 | \n",
+ "
\n",
+ " \n",
+ " 219616 | \n",
+ " ['سامان', 'ساعت'] | \n",
+ " ['femaleSegment'] | \n",
+ " 40 | \n",
+ "
\n",
+ " \n",
+ " 219617 | \n",
+ " ['چشم', 'تنظیم', 'رنگ', 'نرم'] | \n",
+ " ['technology'] | \n",
+ " 523 | \n",
+ "
\n",
+ " \n",
+ " 219618 | \n",
+ " ['خارجی', 'قوی', 'ایرانی خارجی', 'ایرانی'] | \n",
+ " ['femaleSegment'] | \n",
+ " 906 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " keywords \\\n",
+ "219614 ['نتایج زنده', 'نتایج', 'زنده'] \n",
+ "219615 ['زیرنویس', 'فارسی فیلم', 'دانلود زیرنویس'] \n",
+ "219616 ['سامان', 'ساعت'] \n",
+ "219617 ['چشم', 'تنظیم', 'رنگ', 'نرم'] \n",
+ "219618 ['خارجی', 'قوی', 'ایرانی خارجی', 'ایرانی'] \n",
+ "\n",
+ " segments visit count \n",
+ "219614 ['maleSegment', 'varzeshi'] 641 \n",
+ "219615 ['femaleSegment'] 355 \n",
+ "219616 ['femaleSegment'] 40 \n",
+ "219617 ['technology'] 523 \n",
+ "219618 ['femaleSegment'] 906 "
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df = pd.read_csv(\"yektanet.csv\")\n",
+ "df.tail()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "4d3fbe6b",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " قسمت اول\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ " با استفاده از گروهبندی و تابع filter
، وبسایتهایی را انتخاب کنید که کلیدواژهی مربوط به آنها، بیشتر از ۱۴۰۰ وبسایت را شامل میشود. به بیان دیگر، آن لیست کلیدواژه بیش از ۱۴۰۰ بار در دیتافریم تکرار شده باشد. حاصل را در متغیر filtered_df
ذخیره کنید.\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "راهنمایی:\n",
+ " ابتدا تابع groupby
را برای کلیدواژهها اعمال کرده و سپس از از تابع len
برای بررسی تعداد اعضا استفاده کنید. توجه کنید لازم نیست گروهبندی براساس هر عضو داخل آرایهی کلیدواژهها انجام شود.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "1f051715-851e-4865-b14f-dfe975ec0b2b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " keywords | \n",
+ " segments | \n",
+ " visit count | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 1 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 822 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 307 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 778 | \n",
+ "
\n",
+ " \n",
+ " 10 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment', 'varzeshi'] | \n",
+ " 418 | \n",
+ "
\n",
+ " \n",
+ " 16 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 324 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 219597 | \n",
+ " ['صفحه اخبار', 'صفحه', 'اخبار'] | \n",
+ " ['maleSegment'] | \n",
+ " 669 | \n",
+ "
\n",
+ " \n",
+ " 219601 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 742 | \n",
+ "
\n",
+ " \n",
+ " 219608 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['salamat', 'laghari'] | \n",
+ " 472 | \n",
+ "
\n",
+ " \n",
+ " 219612 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 460 | \n",
+ "
\n",
+ " \n",
+ " 219614 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment', 'varzeshi'] | \n",
+ " 641 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
24247 rows × 3 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " keywords segments \\\n",
+ "1 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "3 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "4 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "10 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment', 'varzeshi'] \n",
+ "16 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "... ... ... \n",
+ "219597 ['صفحه اخبار', 'صفحه', 'اخبار'] ['maleSegment'] \n",
+ "219601 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "219608 ['نتایج زنده', 'نتایج', 'زنده'] ['salamat', 'laghari'] \n",
+ "219612 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "219614 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment', 'varzeshi'] \n",
+ "\n",
+ " visit count \n",
+ "1 822 \n",
+ "3 307 \n",
+ "4 778 \n",
+ "10 418 \n",
+ "16 324 \n",
+ "... ... \n",
+ "219597 669 \n",
+ "219601 742 \n",
+ "219608 472 \n",
+ "219612 460 \n",
+ "219614 641 \n",
+ "\n",
+ "[24247 rows x 3 columns]"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "filtered_df = df.groupby(\"keywords\").filter(lambda x : len(x) > 1400)\n",
+ "filtered_df"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "81e5af66",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ " قسمت دوم\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ " اکنون ستونی به نام popularity
را به دیتافریم filtered_df
اضافه کنید که نسبت تعداد بازدید هر وبسایت به مجموع تعداد بازدید تمام وبسایتهای آن کلیدواژه را شامل شود.\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "راهنمایی:\n",
+ "بعد از انجام گروهبندی بر اساس keywords
، تابع transfrom
را روی ستون visit count
اعمال کرده و نسبت بازید هر وبسایت به مجموع بازدیدهای آن گروه کلیدواژه را محاسبه و در ۱۰۰ ضرب کنید.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "a7ccd820-70b9-4d19-ad6e-36fe65c8c16b",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " keywords | \n",
+ " segments | \n",
+ " visit count | \n",
+ " popularity | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 1 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 822 | \n",
+ " 0.016966 | \n",
+ "
\n",
+ " \n",
+ " 3 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 307 | \n",
+ " 0.006337 | \n",
+ "
\n",
+ " \n",
+ " 4 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 778 | \n",
+ " 0.016058 | \n",
+ "
\n",
+ " \n",
+ " 10 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment', 'varzeshi'] | \n",
+ " 418 | \n",
+ " 0.008628 | \n",
+ "
\n",
+ " \n",
+ " 16 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 324 | \n",
+ " 0.006687 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 219597 | \n",
+ " ['صفحه اخبار', 'صفحه', 'اخبار'] | \n",
+ " ['maleSegment'] | \n",
+ " 669 | \n",
+ " 0.014774 | \n",
+ "
\n",
+ " \n",
+ " 219601 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 742 | \n",
+ " 0.015315 | \n",
+ "
\n",
+ " \n",
+ " 219608 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['salamat', 'laghari'] | \n",
+ " 472 | \n",
+ " 0.009742 | \n",
+ "
\n",
+ " \n",
+ " 219612 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment'] | \n",
+ " 460 | \n",
+ " 0.009494 | \n",
+ "
\n",
+ " \n",
+ " 219614 | \n",
+ " ['نتایج زنده', 'نتایج', 'زنده'] | \n",
+ " ['maleSegment', 'varzeshi'] | \n",
+ " 641 | \n",
+ " 0.013230 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
24247 rows × 4 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " keywords segments \\\n",
+ "1 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "3 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "4 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "10 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment', 'varzeshi'] \n",
+ "16 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "... ... ... \n",
+ "219597 ['صفحه اخبار', 'صفحه', 'اخبار'] ['maleSegment'] \n",
+ "219601 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "219608 ['نتایج زنده', 'نتایج', 'زنده'] ['salamat', 'laghari'] \n",
+ "219612 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment'] \n",
+ "219614 ['نتایج زنده', 'نتایج', 'زنده'] ['maleSegment', 'varzeshi'] \n",
+ "\n",
+ " visit count popularity \n",
+ "1 822 0.016966 \n",
+ "3 307 0.006337 \n",
+ "4 778 0.016058 \n",
+ "10 418 0.008628 \n",
+ "16 324 0.006687 \n",
+ "... ... ... \n",
+ "219597 669 0.014774 \n",
+ "219601 742 0.015315 \n",
+ "219608 472 0.009742 \n",
+ "219612 460 0.009494 \n",
+ "219614 641 0.013230 \n",
+ "\n",
+ "[24247 rows x 4 columns]"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "filtered_df['popularity'] = filtered_df.groupby('keywords')['visit count'].transform(lambda x: (x/x.sum()*100))\n",
+ "filtered_df"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "id": "f42669a5-fb7f-4f64-acb8-e026fb310789",
+ "metadata": {},
+ "source": [
+ "\n",
+ "\n",
+ "سلول جوابساز\n",
+ "\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " برای ساختهشدن فایل result.zip
سلول زیر را اجرا کنید. توجه داشته باشید که پیش از اجرای سلول زیر تغییرات اعمال شده در نتبوک را ذخیره کرده باشید (ctrl+s
) تا در صورت نیاز به پشتیبانی امکان بررسی کد شما وجود داشته باشد.\n",
+ "\n",
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "6bc08279-93f4-4c56-bd9d-4e3d457ff6ad",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "File Paths:\n",
+ "['filtered_df.csv', 'yektanet.ipynb']\n"
+ ]
+ }
+ ],
+ "source": [
+ "import zlib\n",
+ "import zipfile\n",
+ "\n",
+ "filtered_df.to_csv('filtered_df.csv', index=True)\n",
+ "\n",
+ "def compress(file_names):\n",
+ " print(\"File Paths:\")\n",
+ " print(file_names)\n",
+ " compression = zipfile.ZIP_DEFLATED\n",
+ " with zipfile.ZipFile(\"result.zip\", mode=\"w\") as zf:\n",
+ " for file_name in file_names:\n",
+ " zf.write('./' + file_name, file_name, compress_type=compression)\n",
+ "\n",
+ "file_names = [\"filtered_df.csv\", \"yektanet.ipynb\"]\n",
+ "compress(file_names)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.8.1"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "44e7e1b8fa2096bd5707ed7fd18b1724a2db25f4c565a7673f8b6e7bfc49d25d"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}