{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "rQ8UhzFpgRra" }, "source": [ "# ការរៀបចំទិន្នន័យ\n", "\n", "[មូលដ្ឋានកំណត់ត្រាដើមពី *វិទ្យាសាស្ត្រទិន្នន័យ៖ ការណែនាំអំពីការរៀនម៉ាស៊ីនសម្រាប់ Python និង Machine Learning Studio ដោយ Lee Stott*](https://github.com/leestott/intro-Datascience/blob/master/Course%20Materials/4-Cleaning_and_Manipulating-Reference.ipynb)\n", "\n", "## ការស្វែងយល់ព័ត៌មាន `DataFrame`\n", "\n", "> **គោលបំណងរៀន៖** នៅចុងផ្នែកនេះ អ្នកគួរតែមានភាពងាយស្រួលក្នុងការស្វែងរកព័ត៌មានទូទៅអំពីទិន្នន័យដែលបានរក្សាទុកក្នុង pandas DataFrames។\n", "\n", "ពេលដែលអ្នកបានផ្ទុកទិន្នន័យរបស់អ្នកចូលក្នុង pandas វានឹងមានទំរង់ជា `DataFrame` ជាច្រើនច្រើនជាងមួយ។ ទោះយ៉ាងណា ប្រសិនបើទិន្នន័យក្នុង `DataFrame` របស់អ្នកមានជួរដេក 60,000 និងជួរឈរ 400 តើអ្នកដឹងដូចម្តេចក្នុងការចាប់ផ្តើមយល់អំពីអ្វីដែលអ្នកកំពុងធ្វើ? សំណាងល្អ pandas ផ្តល់ឧបករណ៍ងាយស្រួលមួយចំនួនសម្រាប់មើលព័ត៌មានទូទៅអំពី `DataFrame` ដោយរហ័ស លើសពីស្រទាប់ជួរដំបូង និងចុងក្រោយ។\n", "\n", "ដើម្បីស្វែងយល់ពីមុខងារនេះ អ្នកនឹងនាំចូលបណ្ណាល័យ Python scikit-learn ហើយប្រើសំណុំទិន្នន័យដ៏ល្បីមួយ ដែលអ្នកវិទ្យាសាស្ត្រទិន្នន័យគ្រប់រូបបានឃើញរាប់រ៉ុកដង៖ សំណុំទិន្នន័យ *Iris* របស់ជីវសាស្ត្រ ប៊ូលរីស្ត៍ Ronald Fisher ដែលបានប្រើក្នុងអត្ថបទរបស់គាត់ឆ្នាំ 1936 \"ការប្រើវាស់វែងច្រើនក្នុងបញ្ហាតាក់ស៊ូម៉ិក\":\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true, "id": "hB1RofhdgRrp", "trusted": false }, "outputs": [], "source": [ "import pandas as pd\n", "from sklearn.datasets import load_iris\n", "\n", "iris = load_iris()\n", "iris_df = pd.DataFrame(data=iris['data'], columns=iris['feature_names'])" ] }, { "cell_type": "markdown", "metadata": { "id": "AGA0A_Y8hMdz" }, "source": [ "### `DataFrame.shape`\n", "យើងបានផ្ទុក Dataset Iris ទៅក្នុងអថេរ `iris_df`។ មុននឹងចូលទៅក្នុងទិន្នន័យ វានឹងមានប្រយោជន៍ដើម្បីដឹងចំនួនចំណុចទិន្នន័យដែលយើងមាន និងទំហំទាំងមូលរបស់ dataset។ វាមានប្រយោជន៍ក្នុងការមើលបរិមាណទិន្នន័យដែលយើងកំពុងដោះស្រាយ។\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "LOe5jQohhulf", "outputId": "fb0577ac-3b4a-4623-cb41-20e1b264b3e9" }, "outputs": [ { "data": { "text/plain": [ "(150, 4)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iris_df.shape" ] }, { "cell_type": "markdown", "metadata": { "id": "smE7AGzOhxk2" }, "source": [ "ដូច្នេះ យើងកំពុងដំណើរការជាតួអក្សរ 150 និងជួរឈរចំនួន 4 នៃទិន្នន័យ។ តួអក្សរនីមួយៗតំណាងឱ្យចំណុចទិន្នន័យមួយ និងជួរឈរនីមួយៗតំណាងឱ្យលក្ខណៈពិសេសមួយដែលពាក់ព័ន្ធនឹងស៊ុមទិន្នន័យ។ ដូច្នេះមូលដ្ឋានទាំងអស់មានចំណុចទិន្នន័យ 150 ដែលមានលក្ខណៈពិសេស 4 គ្រប់គ្រាន់។\n", "\n", "`shape` នៅទីនេះគឺជាគុណលក្ខណៈនៃស៊ុមទិន្នន័យ មិនមែនជាអនុគមន៍ទេ ដូច្នេះវាមិនបញ្ចប់ជាមួយគូវគ្គនៃសញ្ញាវិថីទេ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "d3AZKs0PinGP" }, "source": [ "### `DataFrame.columns`\n", "ឥឡូវនេះយើងមកពិនិត្យកាន់តែជ្រៅទៅលើជួរឈរទិន្នន័យចំនួន ៤។ តើមួយៗក្នុងនោះតំណាងអ្វីខ្លះ? ទ្រព្យសម្បត្តិ `columns` នឹងផ្តល់ឲ្យ​យើងឈ្មោះនៃជួរឈរនៅក្នុង dataframe។\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "YPGh_ziji-CY", "outputId": "74e7a43a-77cc-4c80-da56-7f50767c37a0" }, "outputs": [ { "data": { "text/plain": [ "Index(['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)',\n", " 'petal width (cm)'],\n", " dtype='object')" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iris_df.columns" ] }, { "cell_type": "markdown", "metadata": { "id": "TsobcU_VjCC_" }, "source": [ "ដូចដែលយើងអាចមើលឃើញ មានជួរឈរ​បួន(4)។ លក្ខណៈ `columns` បង្ហាញឲ្យយើងដឹងពីឈ្មោះនៃជួរឈរនិងគ្មានអ្វីផ្សេងទៀត។ លក្ខណៈនេះមានសារៈសំខាន់នៅពេលដែលយើងចង់កំណត់លក្ខណៈពិសេសដែលឯកសារទិន្នន័យមាន។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "2UTlvkjmgRrs" }, "source": [ "### `DataFrame.info`\n", "ចំនួនទិន្នន័យ(ដែលផ្តល់ដោយគុណលក្ខណៈ `shape`) និងឈ្មោះនៃលក្ខណៈឬជួរឈរដែលផ្តល់ដោយគុណលក្ខណៈ `columns` បានប្រាប់យើងអំពីសំណុំទិន្នន័យមួយ។ ឥលូវនេះ យើងចង់ធ្វើយកចូលទៅកាន់សំណុំទិន្នន័យខាងក្នុងជាងមុន។ មុខងារ `DataFrame.info()` គឺមានប្រយោជន៍យ៉ាងខ្លាំងសម្រាប់ការនេះ។\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "dHHRyG0_gRrt", "outputId": "d8fb0c40-4f18-4e19-da48-c8db77d1d3a5", "trusted": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "RangeIndex: 150 entries, 0 to 149\n", "Data columns (total 4 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", " 0 sepal length (cm) 150 non-null float64\n", " 1 sepal width (cm) 150 non-null float64\n", " 2 petal length (cm) 150 non-null float64\n", " 3 petal width (cm) 150 non-null float64\n", "dtypes: float64(4)\n", "memory usage: 4.8 KB\n" ] } ], "source": [ "iris_df.info()" ] }, { "cell_type": "markdown", "metadata": { "id": "1XgVMpvigRru" }, "source": [ "នៅទីនេះ យើងអាចធ្វើការប៉ាន់ស្មានខ្លះៗបាន៖\n", "1. ប្រភេទទិន្នន័យនៃជួរដេកនីមួយៗ៖ ក្នុងឯកសារទិន្នន័យនេះ ទិន្នន័យទាំងអស់ត្រូវបានផ្ទុកជាចំនួនទសភាគចុចហ្រ្វ្លូត 64 ប៊ីត។\n", "2. លេខនៃតម្លៃមិនមែនជាសូន្យ៖ ការដោះស្រាយតម្លៃសូន្យគឺជាជំហានសំខាន់មួយក្នុងការរៀបចំទិន្នន័យ។ វានឹងត្រូវបានដោះស្រាយនៅពេលក្រោយក្នុងសៀវភៅកំណត់សម្គាល់។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "IYlyxbpWFEF4" }, "source": [ "### DataFrame.describe()\n", "សន្មត់ថាយើងមានទិន្នន័យច្រើនជាលេខនៅក្នុង dataset របស់យើង។ ការគណនាស្ថិតិមួយប៉ុណ្ណោះ ដូចជាមធ្យមភាព មេឌៀន ចំណុចបួនជាប់លំដាប់ ល។ អាចធ្វើបានលើ១១ាយជួរឈរ ដោយឡែក។ មុខងារ `DataFrame.describe()` នាំឱ្យយើងទទួលបានសង្ខេបស្ថិតិ នៃជួរឈរលេខនានានៅក្នុង dataset ។\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 297 }, "id": "tWV-CMstFIRA", "outputId": "4fc49941-bc13-4b0c-a412-cb39e7d3f289" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sepal length (cm)sepal width (cm)petal length (cm)petal width (cm)
count150.000000150.000000150.000000150.000000
mean5.8433333.0573333.7580001.199333
std0.8280660.4358661.7652980.762238
min4.3000002.0000001.0000000.100000
25%5.1000002.8000001.6000000.300000
50%5.8000003.0000004.3500001.300000
75%6.4000003.3000005.1000001.800000
max7.9000004.4000006.9000002.500000
\n", "
" ], "text/plain": [ " sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)\n", "count 150.000000 150.000000 150.000000 150.000000\n", "mean 5.843333 3.057333 3.758000 1.199333\n", "std 0.828066 0.435866 1.765298 0.762238\n", "min 4.300000 2.000000 1.000000 0.100000\n", "25% 5.100000 2.800000 1.600000 0.300000\n", "50% 5.800000 3.000000 4.350000 1.300000\n", "75% 6.400000 3.300000 5.100000 1.800000\n", "max 7.900000 4.400000 6.900000 2.500000" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iris_df.describe()" ] }, { "cell_type": "markdown", "metadata": { "id": "zjjtW5hPGMuM" }, "source": [ "លទ្ធផលខាងលើបង្ហាញពីចំនួនតុល្យឯកតាទិន្នន័យសរុប មធ្យម គោលឆ្នាំត្រង់ កម្រិតអប្បបរមា ជួរចុះក្រោម(២៥%), មេឌាន(៥០%), ជួរឧទ្ធម្ភ(៧៥%) និងតម្លៃអតិបរមារបស់ក្រុមជួរឈរ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "-lviAu99gRrv" }, "source": [ "### `DataFrame.head`\n", "ជាមួយនឹងមុខងារ និងគុណលក្ខណៈទាំងអស់ខាងលើ យើងបានទទួលបានទិដ្ឋភាពកំណត់កម្រិតកំពូលនៃសំណុំទិន្នន័យ។ យើងដឹងថាមានចំនួនចំណុចទិន្នន័យប៉ុន្មាន មានលក្ខណៈប៉ុន្មាន ប្រភេទទិន្នន័យរបស់លក្ខណៈនីមួយៗ និងចំនួនតម្លៃមិនមែន null សម្រាប់លក្ខណៈនីមួយៗ។\n", "\n", "ឥឡូវនេះពេលវេលាដើម្បីមើលទិន្នន័យផ្ទាល់។ យើងមកមើលថាតួរដេកមួយចំនួនដំបូង(ចំណុចទិន្នន័យមួយចំនួនដំបូង) នៃ `DataFrame` របស់យើងមើលទៅដូចម្តេច:\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 204 }, "id": "DZMJZh0OgRrw", "outputId": "d9393ee5-c106-4797-f815-218f17160e00", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sepal length (cm)sepal width (cm)petal length (cm)petal width (cm)
05.13.51.40.2
14.93.01.40.2
24.73.21.30.2
34.63.11.50.2
45.03.61.40.2
\n", "
" ], "text/plain": [ " sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)\n", "0 5.1 3.5 1.4 0.2\n", "1 4.9 3.0 1.4 0.2\n", "2 4.7 3.2 1.3 0.2\n", "3 4.6 3.1 1.5 0.2\n", "4 5.0 3.6 1.4 0.2" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iris_df.head()" ] }, { "cell_type": "markdown", "metadata": { "id": "EBHEimZuEFQK" }, "source": [ "ជា​​​ចេញ​ផល​នៅ​ទីនេះ​យើង​អាច​ឃើញ​ទន្សាយ(៥)​​ចំនួន​​នៃ​ទិន្នន័យ។ ប្រសិន​បើយើង​មើល​នៅ​លេខសន្ទស្សន៍​ខាងឆ្វេង យើង​រក​ឃើញ​ថា​ទាំងនេះ​ជា​បន្ទាត់​ប្រាំ​ដំបូង។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "oj7GkrTdgRry" }, "source": [ "### លំហាត់៖\n", "\n", "ពីឧទាហរណ៍ដែលបានផ្តល់ខាងលើ វាច្បាស់ហើយថា ជាដំណើរការស្វ័យប្រវត្តិ `DataFrame.head` បញ្ចូនជួរដេកដំបូងប្រាំនៃ `DataFrame`។ នៅក្នុងក្រឡាចត្រង់កូដខាងក្រោម អ្នកអាចស្វែងរកវិធីបង្ហាញជួរដេកច្រើនជាងប្រាំបានទេ?\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true, "id": "EKRmRFFegRrz", "trusted": false }, "outputs": [], "source": [ "# Hint: Consult the documentation by using iris_df.head?" ] }, { "cell_type": "markdown", "metadata": { "id": "BJ_cpZqNgRr1" }, "source": [ "### `DataFrame.tail`\n", "វិធីមួយផ្សេងទៀតនៃការមើលទិន្ន័យអាចមកពីចុង (ជំនួសពីការចាប់ផ្តើម)។ ផ្នែកបំផុតនៃ `DataFrame.head` គឺ `DataFrame.tail` ដែលត្រឡប់មកវិញជួរដកចុងបញ្ចប់បួនចុងក្រោយនៃ `DataFrame` ៖\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 0 }, "id": "heanjfGWgRr2", "outputId": "6ae09a21-fe09-4110-b0d7-1a1fbf34d7f3", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sepal length (cm)sepal width (cm)petal length (cm)petal width (cm)
1456.73.05.22.3
1466.32.55.01.9
1476.53.05.22.0
1486.23.45.42.3
1495.93.05.11.8
\n", "
" ], "text/plain": [ " sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)\n", "145 6.7 3.0 5.2 2.3\n", "146 6.3 2.5 5.0 1.9\n", "147 6.5 3.0 5.2 2.0\n", "148 6.2 3.4 5.4 2.3\n", "149 5.9 3.0 5.1 1.8" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "iris_df.tail()" ] }, { "cell_type": "markdown", "metadata": { "id": "31kBWfyLgRr3" }, "source": [ "នៅក្នុង​អនុវត្តន៍​វិជ្ជាមាន​ប្រយោជន៍​នៅ​ក្នុង​ការ​អាច​ពិនិត្យមើល​ជួរដេក​ដំបូង​ជាច្រើន ឬ​ជួរដេកចុងក្រោយ​ជាច្រើន​របស់ `DataFrame` បានយ៉ាងងាយស្រួល ពិសេសនៅពេលដែលអ្នកកំពុងស្វែងរក​តម្លៃឆ្លងច្រាំង​នៅក្នុងឈុតទិន្នន័យដែលរៀបចំតាមលំដាប់។\n", "\n", "មុខងារ និងគុណលក្ខណៈទាំងអស់ដែលបានបង្ហាញខាងលើជាមួយនឹងឧទាហរណ៍កូដបានជួយឲ្យយើងទទួលបានទិដ្ឋភាពនិងអារម្មណ៍លើទិន្នន័យ។\n", "\n", "> **ចំណាំ៖** ទោះបីជាត្រឹមតែ​មើលព័ត៌មានអំពី Metadata អំពីព័ត៌មាន​នៅក្នុង DataFrame ឬតម្លៃដំបូងនិងចុងក្រោយប៉ុណ្ណោះ អ្នកក៏អាចទទួលបានយោបល់ភ្លាមៗអំពីទំហំ រាងកាយ និងមាតិកា​នៃទិន្នន័យដែលអ្នកកំពុងដោះស្រាយ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "TvurZyLSDxq_" }, "source": [ "### ទិន្នន័យដែលខ្វះ\n", "ចូលចិត្តយើងចូលទៅក្នុងទិន្នន័យដែលខ្វះ។ ទិន្នន័យដែលខ្វះមានកើតឡើងពេលដែលគ្មានតម្លៃបានរក្សាទុកក្នុងខ្នាតខ្លះៗ។ \n", "\n", "យើងឧទាហរណ៍៖ គេនិយាយថាមនុស្សម្នាក់ព្រមព្រៀងពីទម្ងន់របស់គាត់ ហើយមិនបំពេញវាលទម្ងន់នៅក្នុងការស្ទង់មតិ។ បន្ទាប់មក តម្លៃទម្ងន់សម្រាប់មនុស្សនោះនឹងខ្វះ។ \n", "\n", "ភាគច្រើននៅក្នុងឯកសារទិន្នន័យពិភពលោកពិត តម្លៃដែលខ្វះនឹងកើតមាន។\n", "\n", "**របៀបដែល Pandas ដោះស្រាយទិន្នន័យដែលខ្វះ**\n", "\n", "\n", "Pandas ដោះស្រាយតម្លៃដែលខ្វះពីរផ្លូវ។ ជាលេខមួយដែលអ្នកបានឃើញមុននេះនៅក្នុងផ្នែកមុនៈ `NaN` ឬ Not a Number។ វាជាតម្លៃពិសេសមួយដែលជាផ្នែកនៃការបញ្ជាក់ IEEE floating-point ហើយវាត្រូវបានប្រើសំរាប់បង្ហាញតែតម្លៃ floating-point ដែលខ្វះប៉ុណ្ណោះ។\n", "\n", "សំរាប់តម្លៃដែលខ្វះក្រៅពី float, pandas ប្រើវត្ថុ Python `None`។ បើទោះបីវាហាក់ដូចជារអិលថ្លៃថាអ្នកនឹងជួបប្រទៈតម្លៃពីរប្រភេទខុសគ្នាដែលនិយាយអំពីអ្វីដែលដូចគ្នាពិតប្រាកដ ក៏មានហេតុខាងក្រោយដែលមានមូលដ្ឋានល្អសំរាប់ការប្រើប្រាស់នេះ ហើយពិតជាក្នុងការអនុវត្ត វagde pandas អាចផ្ដល់ការប្រព្រឹត្តល្អសម្រាប់ករណីភាគច្រើន។ ទោះជាយ៉ាងណា ទាំង `None` និង `NaN` មានការកំណត់ដែលអ្នកត្រូវចងចាំពាក់ព័ន្ធនឹងរបៀបដែលពួកវាអាចត្រូវបានប្រើ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "lOHqUlZFgRr5" }, "source": [ "### `None`: ទិន្នន័យដែលខ្វះមិនមែនជាប្រភេទ float\n", "ដោយសារតែ `None` មកពី Python វាមិនអាចប្រើបានក្នុង NumPy និង pandas arrays ដែលមិនមែនជាប្រភេទទិន្នន័យ `'object'` ទេ។ ចងចាំថា NumPy arrays (និងរចនាសម្ព័ន្ធទិន្នន័យនៅក្នុង pandas) អាចមានបានតែក្នុងលក្ខណៈប្រភេទទិន្នន័យតែមួយប៉ុណ្ណោះ។ នេះគឺជាវត្ថុដែលផ្តល់ឱ្យពួកវាមានអំណាចយ៉ាងសំខាន់សម្រាប់ការដំណើរការទិន្នន័យក្នុងមាឌធំ និងការគណនា ប៉ុន្តែមិនអាចបត់បែនបានយូរទេ។ អារេបែបនេះត្រូវប្រើការកំណត់ប្រភេទទិន្នន័យទៅ “lowest common denominator” វា​គឺជាប្រភេទទិន្នន័យដែលនឹងគ្របដណ្តប់លើអ្វីគ្រប់យ៉ាងនៅក្នុងអារេ។ នៅពេលមាន `None` នៅក្នុងអារេ នោះមានន័យថាអ្នកកំពុងប្រើវាជាមួយអ объекта Python។\n", "\n", "ដើម្បីមើលឃើញអំពីការធ្វើការ នេះ សូមពិចារណាអារេគំរូដូចតទៅ (ចំណាំ `dtype` សម្រាប់វា):\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "QIoNdY4ngRr7", "outputId": "92779f18-62f4-4a03-eca2-e9a101604336", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "array([2, None, 6, 8], dtype=object)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "\n", "example1 = np.array([2, None, 6, 8])\n", "example1" ] }, { "cell_type": "markdown", "metadata": { "id": "pdlgPNbhgRr7" }, "source": [ "យុទ្ធសាស្រ្តពិតប្រាកដនៃប្រភេទទិន្នន័យ upcast មានផលប៉ះពាល់ពីរជាមួយវា។ ជាលើកដំបូង ប្រតិបត្តិការនឹងត្រូវបានអនុវត្តនៅកំរិតកូដ Python ដែលបានបកប្រែ ជាជំនួសជាកូដ NumPy ដែលបានបញ្ចូល។ ពិតប្រាកដណាស់ នេះមានន័យថា ប្រតិបត្តិការណាមួយដែលពាក់ព័ន្ធជាមួយ `Series` ឬ `DataFrames` ដែលមាន `None` នៅក្នុងនឹងយឺតជាង។ គួរឱ្យមាន សំណល់សម្រាប់អ្នកប្រហែលមិនបានយល់ពីការកកើតនៃការជួបប្រទៈនេះ ទោះយ៉ាងណា សម្រាប់ទិន្នន័យធំនោះ វាអាចក្លាយទៅជាបញ្ហា។\n", "\n", "ផលប៉ះពាល់ទីពីរមកពីលទ្ធផលទីមួយ។ ពីព្រោះ `None` មានន័យថាលេងស្ទើរ `Series` ឬ `DataFrame`s ត្រឡប់ទៅជាសកល Python ត្រង់ផ្សងព្រមវា នឹងប្រើ NumPy/pandas សរុបផ្ទៃដូចជា `sum()` ឬ `min()` លើអារេដែលមានតម្លៃ ``None`` នឹងធ្វើឲ្យមានកំហុសទូទៅ៖\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 292 }, "id": "gWbx-KB9gRr8", "outputId": "ecba710a-22ec-41d5-a39c-11f67e645b50", "trusted": false }, "outputs": [ { "ename": "TypeError", "evalue": "ignored", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mexample1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/numpy/core/_methods.py\u001b[0m in \u001b[0;36m_sum\u001b[0;34m(a, axis, dtype, out, keepdims, initial, where)\u001b[0m\n\u001b[1;32m 45\u001b[0m def _sum(a, axis=None, dtype=None, out=None, keepdims=False,\n\u001b[1;32m 46\u001b[0m initial=_NoValue, where=True):\n\u001b[0;32m---> 47\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mumr_sum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkeepdims\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minitial\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mwhere\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 48\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 49\u001b[0m def _prod(a, axis=None, dtype=None, out=None, keepdims=False,\n", "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'int' and 'NoneType'" ] } ], "source": [ "example1.sum()" ] }, { "cell_type": "markdown", "metadata": { "id": "LcEwO8UogRr9" }, "source": [ "**ចំណុចសង្ខេប៖** ការបូក (និងប្រតិបត្តិការផ្សេងៗ) រវាងលេខគ inteira និងតម្លៃ `None` គឺមិនបានកំណត់ ហើយអាចកំណត់អ្វីដែលអ្នកអាចធ្វើបានជាមួយឯកសារទិន្នន័យដែលមានវា។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "pWvVHvETgRr9" }, "source": [ "### `NaN`: តម្លៃស្ពោះដែលបាត់​\n", "\n", "ផ្ទុយទៅវិញពី `None` NumPy (ហើយក៏ pandas ផងដែរ) គាំទ្រ `NaN` សម្រាប់ប្រតិបត្តិការលឿនជាបន្ទាត់ចម្ការ និង ufuncs របស់វា។ ព័ត៌មានអាក្រក់គឺថា គណនាគណិតណាមួយដែលធ្វើលើ `NaN` ស្មើនឹងបង្កើតជា `NaN` ជានិច្ច។ ឧទាហរណ៍:\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "rcFYfMG9gRr9", "outputId": "699e81b7-5c11-4b46-df1d-06071768690f", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "nan" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.nan + 1" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "BW3zQD2-gRr-", "outputId": "4525b6c4-495d-4f7b-a979-efce1dae9bd0", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "nan" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.nan * 0" ] }, { "cell_type": "markdown", "metadata": { "id": "fU5IPRcCgRr-" }, "source": [ "សេចក្តីល្អ៖ ការជួសជុលតម្លៃលើអារេដែលមាន `NaN` នៅក្នុងពួកវា មិនបង្កើតកំហុសឡើយ។ សេចក្តីអាក្រក់៖ លទ្ធផលមិនមានប្រយោជន៍ស្មើគ្នាឡើយ៖\n" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "LCInVgSSgRr_", "outputId": "fa06495a-0930-4867-87c5-6023031ea8b5", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "(nan, nan, nan)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example2 = np.array([2, np.nan, 6, 8]) \n", "example2.sum(), example2.min(), example2.max()" ] }, { "cell_type": "markdown", "metadata": { "id": "nhlnNJT7gRr_" }, "source": [ "### ការហាត់ការ:\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true, "id": "yan3QRaOgRr_", "trusted": false }, "outputs": [], "source": [ "# What happens if you add np.nan and None together?\n" ] }, { "cell_type": "markdown", "metadata": { "id": "_iDvIRC8gRsA" }, "source": [ "សូមចងចាំ៖ `NaN` គឺសម្រាប់តម្លៃបញ្ចោទទិសចុចបន្ទាត់ហោះហើរដែលបាត់បង់តែប៉ុណ្ណោះ; មិនមាន `NaN` សម្រាប់គ្រឹះទិន្នន័យចំនួនគត់ ខ្សែអក្សរ ឬតម្លៃប៊ូលែនទេ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "kj6EKdsAgRsA" }, "source": [ "### `NaN` និង `None`: តម្លៃ null ក្នុង pandas\n", "\n", "ថ្វីត្បិតជា `NaN` និង `None` អាចមានអាកប្បកិរិយាដូចមិនដូចគ្នាក្នុងបរិមាណមួយ ក្តី pandas ត្រូវបានសិក្សាឡើងដើម្បីដោះស្រាយពួកវាដោយអាចប្ដូរប្រក់ប្រជា។ ដើម្បីមើលពីអ្វីដែលយើងមានន័យ សូមពិចារណា `Series` នៃពិន្ទុលេខអាំងតេជឺ:\n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Nji-KGdNgRsA", "outputId": "36aa14d2-8efa-4bfd-c0ed-682991288822", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "0 1\n", "1 2\n", "2 3\n", "dtype: int64" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "int_series = pd.Series([1, 2, 3], dtype=int)\n", "int_series" ] }, { "cell_type": "markdown", "metadata": { "id": "WklCzqb8gRsB" }, "source": [ "### លំហាត់៖\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true, "id": "Cy-gqX5-gRsB", "trusted": false }, "outputs": [], "source": [ "# Now set an element of int_series equal to None.\n", "# How does that element show up in the Series?\n", "# What is the dtype of the Series?\n" ] }, { "cell_type": "markdown", "metadata": { "id": "WjMQwltNgRsB" }, "source": [ "ក្នុងដំណើរការសម្រាប់បម្លែងប្រភេទទិន្នន័យទៅឱ្យមានភាពស្រដៀងគ្នាក្នុង `Series` និង `DataFrame`s pandas នឹងត្រូវចូលចិត្តប្តូរតម្លៃខ្វះពី `None` ទៅ `NaN` ។ ដោយសារតែមុខងារ ဒီហើយ វាអាចជួយគិតថា `None` និង `NaN` គឺជាប្រភេទ \"null\" ពីរប្រភេទផ្សេងគ្នាក្នុង pandas ។ ត្រឹមត្រូវហើយ នៅមានវិធីសាស្រ្តសំខាន់មួយចំនួនដែលអ្នកនឹងប្រើដើម្បីដោះស្រាយបញ្ហាតម្លៃខ្វះក្នុង pandas ដែលបញ្ជាក់ពីគំនិតនេះនៅក្នុងឈ្មោះរបស់ពួកវា៖\n", "\n", "- `isnull()`: បង្កើតម៉ាស Boolean បង្ហាញតម្លៃខ្វះ\n", "- `notnull()`: ផ្ទុយពី `isnull()`\n", "- `dropna()`: ត្រឡប់ជាកំណែត្រងនៃទិន្នន័យ\n", "- `fillna()`: ត្រឡប់ជាកំណែចម្លងនៃទិន្នន័យដែលបំពេញឬប៉ាន់ប្រមាណតម្លៃខ្វះ\n", "\n", "ទាំងនេះគឺជាវិធីសាស្រ្តសំខាន់ដែលត្រូវចេះល្អ និងមានភាពសឿនឆាប់រំលឹក ដូចនេះយើងចង់ពិនិត្យមើលពួកវា រៀងរាល់មួយដោយជ្រៅជាងនេះ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "Yh5ifd9FgRsB" }, "source": [ "### ការរកឃើញតម្លៃ null\n", "\n", "ឥឡូវនេះ យើងបានយល់ពីសារៈសំខាន់នៃតម្លៃខ្វះខាតហើយ យើងត្រូវការរកឃើញពួកវាក្នុងទិន្នន័យរបស់យើង មុនពេលដោះស្រាយពួកវា។\n", "ទាំង `isnull()` និង `notnull()` គឺជាវិធីសាស្ត្រចម្បងរបស់អ្នកសម្រាប់រកឃើញទិន្នន័យ null។ ទាំងពីរនេះត្រឡប់មកជា mask Boolean លើទិន្នន័យរបស់អ្នក។\n" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true, "id": "e-vFp5lvgRsC", "trusted": false }, "outputs": [], "source": [ "example3 = pd.Series([0, np.nan, '', None])" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "1XdaJJ7PgRsC", "outputId": "92fc363a-1874-471f-846d-f4f9ce1f51d0", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "0 False\n", "1 True\n", "2 False\n", "3 True\n", "dtype: bool" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example3.isnull()" ] }, { "cell_type": "markdown", "metadata": { "id": "PaSZ0SQygRsC" }, "source": [ "សូមមើលលម្អិតលើលទ្ធផល។ តើមានអ្វីដែលធ្វើឲ្យអ្នកភ្ញាក់ផ្អើលទេ? ខណៈពេលដែល `0` គឺជាតម្លៃសូន្យគណិតវិទ្យា តែវាបានទទួលស្គាល់ថាជាចំនួនគត់ល្អមួយ ហើយ pandas ក៏ទទួលការពិចារណាដូច្នោះដែរ។ `''` មានកម្រិតស្មុគស្មាញបន្តិចបន្តួច។ ខណៈពេលដែលយើងប្រើវានៅផ្នែកទី ១ ដើម្បីតំណាងឲ្យតម្លៃខ្សែអក្សរចន្លោះវា តែវាបានក្លាយជាវត្ថុខ្សែអក្សរម្នាក់ និងមិនមែនជាតំណាងសម្រាប់តម្លៃសូន្យតាមដែល pandas ពិចារណាជាអនុស្សាវរីយ៍ទេ។\n", "\n", "ឥឡូវនេះ យើងចង់បង្វិលវាពីមុខទៅក្រោយ ហើយប្រើវិធីសាស្រ្តទាំងនេះនៅក្នុងរបៀបដែលអ្នកនឹងប្រើប្រាស់ពួកវាពីរបៀបជាក់ស្តែងជាងមុន។ អ្នកអាចប្រើម៉ាស Boolean ទៅមានតួនាទីជាស៊េរី ``Series`` ឬ ``DataFrame`` indexes ដោយផ្ទាល់ ដែលអាចមានប្រយោជន៍ពេលព្យាយាមធ្វើការជាមួយតម្លៃខ្វះខាត (ឬមាន) ដែលបានបំបែកចេញ។\n", "\n", "ប្រសិនបើយើងចង់បានចំនួនសរុបនៃតម្លៃខ្វះខាត យើងអាចធ្វើការប្រមាណបូកពីម៉ាសដែលបង្កើតដោយវិធីសាស្រ្ត `isnull()` បានណាស់។\n" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "JCcQVoPkHDUv", "outputId": "001daa72-54f8-4bd5-842a-4df627a79d4d" }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example3.isnull().sum()" ] }, { "cell_type": "markdown", "metadata": { "id": "PlBqEo3mgRsC" }, "source": [ "### លំហាត់៖\n" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true, "id": "ggDVf5uygRsD", "trusted": false }, "outputs": [], "source": [ "# Try running example3[example3.notnull()].\n", "# Before you do so, what do you expect to see?\n" ] }, { "cell_type": "markdown", "metadata": { "id": "D_jWN7mHgRsD" }, "source": [ "**ចំណុចសំខាន់**៖ វិធីសាស្រ្ត `isnull()` និង `notnull()` ទាំងពីរផ្តល់លទ្ធផលដូចគ្នា​នៅពេលអ្នកប្រើប្រាស់ពួកវាក្នុង DataFrames៖ ពួកវាបង្ហាញលទ្ធផល និងសន្ទស្សន៍នៃលទ្ធផលទាំងនោះ ដែលនឹងជួយអ្នកយ៉ាងខ្លាំងនៅពេលអ្នកប្រយុទ្ធជាមួយទិន្នន័យរបស់អ្នក។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "BvnoojWsgRr4" }, "source": [ "### ការដោះស្រាយទិន្នន័យដែលខ្វះ\n", "\n", "> **គោលបំណងរៀន:** នៅចុងផ្នែកនេះ អ្នកគួរតែដឹងពីរបៀបនិងពេលដែលត្រូវប្តូរឬដកតម្លៃ null ចេញពី DataFrames។\n", "\n", "គំរូ Machine Learning មិនអាចដោះស្រាយទិន្នន័យដែលខ្វះដោយខ្លួនឯងបានទេ។ ដូច្នេះ មុនពេលផ្ញើទិន្នន័យចូលទៅក្នុងគំរូ យើងត្រូវតែដោះស្រាយតម្លៃខ្វះទាំងនេះ។\n", "\n", "របៀបដោះស្រាយទិន្នន័យខ្វះមានការជួញដូរឆ្លាតវៃ មានអនុលោមអាស្រ័យលើវា អាចប៉ះពាល់ដល់វិភាគចុងក្រោយរបស់អ្នក និងលទ្ធផលក្នុងពិភពជាក់ស្តែង។\n", "\n", "មានរបៀបសំខាន់ចម្បងពីរនៃការដោះស្រាយទិន្នន័យខ្វះ៖\n", "\n", "\n", "1. លុបជួរដែលមានតម្លៃខ្វះចេញ\n", "2. ប្តូរតម្លៃខ្វះដោយតម្លៃផ្សេងទៀត\n", "\n", "យើងនឹងពិភាក្សាអំពីវិធីទាំងពីរនេះ និងអត្ថប្រយោជន៍និងគុណវិបត្តិរបស់ពួកវាជារយៈលម្អិត។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "3VaYC1TvgRsD" }, "source": [ "### ការលុបតម្លៃទទេ\n", "\n", "បរិមាណទិន្នន័យដែលយើងផ្តល់ចូលទៅកាន់ម៉ូដែលរបស់យើងមានឥទ្ធិពលផ្ទាល់លើកម្រិតប្រសិទ្ធភាពរបស់វា។ ការលុបតម្លៃទទេមានន័យថាយើងកំពុងកាត់ចំនួនចំណុចទិន្នន័យ ហើយដូច្នេះក៏កាត់បន្ថយទំហំឯកសារទិន្នន័យផងដែរ។ ដូច្នេះ គឺមានការណែនាំឱ្យលុបជួរដេកដែលមានតម្លៃទទេនៅពេលដែលឯកសារទិន្នន័យមានទំហំធំ។\n", "\n", "ករណីផ្សេងទៀតអាចជាជួរដេកឬជួរឈរមួយមានតម្លៃខ្វះខាតច្រើន។ បន្ទាប់មក វាអាចត្រូវបានលុបចោល ព្រោះវាមិននាំមកនូវតម្លៃច្រើនសម្រាប់វិភាគរបស់យើងទេ ដោយសារតែទិន្នន័យភាគច្រើនខ្វះសម្រាប់ជួរដេក/ជួរឈរនោះ។\n", "\n", "លើសពីការកំណត់តម្លៃខ្វះ យ៉ាង pandas ផ្តល់នូវវិធីងាយស្រួលក្នុងការលុបតម្លៃទទេ ចេញពី `Series` និង `DataFrame`។ ដើម្បីឃើញវាក្នុងសកម្មភាព សូមត្រឡប់ទៅ `example3`។ មុខងារ `DataFrame.dropna()` ជួយក្នុងការលុបជួរដេកដែលមានតម្លៃទទេ។\n" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "7uIvS097gRsD", "outputId": "c13fc117-4ca1-4145-a0aa-42ac89e6e218", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "0 0\n", "2 \n", "dtype: object" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example3 = example3.dropna()\n", "example3" ] }, { "cell_type": "markdown", "metadata": { "id": "hil2cr64gRsD" }, "source": [ "សូមចំណាំថា នេះគួរត្រូវមើលទៅដូចជាផលចេញពី `example3[example3.notnull()]`។ ខុសគ្នាទៅនេះ គឺថា មិនបានបញ្ជាក់ត្រឹមតែតម្លៃដែលបានដាក់ម៉ាសទេ ប៉ុន្តែ `dropna` បានដកតម្លៃដែលខ្វះទាំងនោះចេញពី `Series` `example3`។\n", "\n", "ដោយសារតែ DataFrames មានពីរ និងមិន មានទំហំវាត្រូវបានផ្តល់ជម្រើសច្រើនសម្រាប់ការដកចេញទិន្នន័យ។\n" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 142 }, "id": "an-l74sPgRsE", "outputId": "340876a0-63ad-40f6-bd54-6240cdae50ab", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
01.0NaN7
12.05.08
2NaN6.09
\n", "
" ], "text/plain": [ " 0 1 2\n", "0 1.0 NaN 7\n", "1 2.0 5.0 8\n", "2 NaN 6.0 9" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example4 = pd.DataFrame([[1, np.nan, 7], \n", " [2, 5, 8], \n", " [np.nan, 6, 9]])\n", "example4" ] }, { "cell_type": "markdown", "metadata": { "id": "66wwdHZrgRsE" }, "source": [ "(តើអ្នកកត់សម្គាល់ទេថា pandas បានបម្លែងពីជួរឈរចំណួនពីរជា float ដើម្បីគាំទ្រ `NaN`?)\n", "\n", "អ្នកមិនអាចលុបតម្លៃតែមួយចេញពី `DataFrame` ទេ ដូច្នេះអ្នកត្រូវតែលុបជួរដេកឬជួរឈរ ពេញលេញ។ អាស្រ័យតាមអ្វីដែលអ្នកកំពុងធ្វើ អ្នកអាចចង់ធ្វើមួយក្នុងចំណោមបាន ហើយដូច្នេះ pandas ផ្តល់ជម្រើសទាំងពីរឲ្យអ្នក។ ពីព្រោះនៅក្នុងវិទ្យាសាស្ត្រទិន្នន័យ ជួរឈរតំណាងឲ្យអថេរ ហើយជួរដេកតំណាងឲ្យការសង្កេត អ្នកតែងតែលុបជួរដេកនៃទិន្នន័យ; ការកំណត់លំនាំដើមសម្រាប់ `dropna()` គឺលុបជួរដេកទាំងអស់ដែលមានតម្លៃសូន្យណាមួយ៖\n" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 80 }, "id": "jAVU24RXgRsE", "outputId": "0b5e5aee-7187-4d3f-b583-a44136ae5f80", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
12.05.08
\n", "
" ], "text/plain": [ " 0 1 2\n", "1 2.0 5.0 8" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example4.dropna()" ] }, { "cell_type": "markdown", "metadata": { "id": "TrQRBuTDgRsE" }, "source": [ "ប្រសិនបើចាំបាច់ អ្នកអាចលុបតម្លៃ NA ពីជួរឈរ។ ប្រើ `axis=1` ដើម្បីធ្វើដូចនេះ៖\n" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 142 }, "id": "GrBhxu9GgRsE", "outputId": "ff4001f3-2e61-4509-d60e-0093d1068437", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
2
07
18
29
\n", "
" ], "text/plain": [ " 2\n", "0 7\n", "1 8\n", "2 9" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example4.dropna(axis='columns')" ] }, { "cell_type": "markdown", "metadata": { "id": "KWXiKTfMgRsF" }, "source": [ "សូមចំណាំថានេះអាចបណ្តាលឱ្យមានការបាត់បង់ទិន្នន័យច្រើនដែលអ្នកប្រហែលជាចង់រក្សាទុកពិសេសនៅក្នុងទិន្នន័យតូចៗ។ តើយ៉ាងដូចម្តេចបើអ្នកចង់បញ្ឈប់តែជួរដេកឬជួរឈរដែលមានតម្លៃទទេច្រើន ឬសូម្បីតែទាំងអស់គ្នាឲ្យបានបាត់បង់? អ្នកកំណត់ការដាក់តម្លៃនោះនៅក្នុង `dropna` ជាមួយប៉ារ៉ាម៉ែត្រ `how` និង `thresh`។\n", "\n", "លំនាំដើមគឺ `how='any'` (បើអ្នកចង់ពិនិត្យផ្សេងទៀតដោយខ្លួនឯង ឬមើលថា តើវិធីសាស្ត្រផ្សេងទៀតមានអ្វីខ្លះ អ្នកអាចរត់ `example4.dropna?` ក្នុងកោដ្ឋិកូដមួយ)។ អ្នកអាចជ្រើសរើស `how='all'` ដើម្បីបញ្ឈប់តែជួរដេកឬជួរឈរដែលមានតម្លៃទទេទាំងអស់ប៉ុណ្ណោះ។ មកដោះស្រាយឧទាហរណ៍ `DataFrame` របស់យើងឲ្យធំជាងនេះដើម្បីឃើញការបញ្ជាក់វាកើតឡើងយ៉ាងដូចម្តេចនៅក្នុងលំហាត់បន្ទាប់។\n" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 142 }, "id": "Bcf_JWTsgRsF", "outputId": "72e0b1b8-52fa-4923-98ce-b6fbed6e44b1", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
01.0NaN7NaN
12.05.08NaN
2NaN6.09NaN
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 1.0 NaN 7 NaN\n", "1 2.0 5.0 8 NaN\n", "2 NaN 6.0 9 NaN" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example4[3] = np.nan\n", "example4" ] }, { "cell_type": "markdown", "metadata": { "id": "pNZer7q9JPNC" }, "source": [ "> ចំណុចសំខាន់ៗ៖ \n", "1. ការបោះបង់តម្លៃ null គឺជាគំនិតល្អបើតែក្រុមទិន្នន័យធំប៉ុណ្ណោះ។ \n", "2. ជួរឈរឬក៏កូឡុំទាំងមូលអាចត្រូវបានបោះបង់ ប្រសិនបើវាអត់មានទិន្នន័យភាគច្រើន។ \n", "3. វិធីសាស្រ្ត `DataFrame.dropna(axis=)` ជួយក្នុងការកែចេញតម្លៃ null។ អេហ្ស៊ីង `axis` សម្គាល់ថាតើត្រូវបោះបង់ជួរឈរឬកូឡុំ។ \n", "4. អេហ្ស៊ីង `how` ក៏អាចប្រើបានផងដែរ។ ដោយលំនាំដើម វាត្រូវបានកំណត់ជា `any`។ ដូច្នេះ វាបោះបង់តែនូវជួរឈរ/កូឡុំដែលមានតម្លៃ null យ៉ាងហោចណាស់មួយ។ វាអាចកំណត់ជា `all` ដើម្បីបញ្ជាក់ថា យើងនឹងបោះបង់តែនូវជួរឈរ/កូឡុំនោះទេដែលមានតម្លៃមួយចំនួនសុទ្ធ null។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "oXXSfQFHgRsF" }, "source": [ "### លំហាត់:\n" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true, "id": "ExUwQRxpgRsF", "trusted": false }, "outputs": [], "source": [ "# How might you go about dropping just column 3?\n", "# Hint: remember that you will need to supply both the axis parameter and the how parameter.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "38kwAihWgRsG" }, "source": [ "ប៉ារ៉ាម៉ែត្រ `thresh` អនុញ្ញាតឱ្យអ្នកបញ្ជាការតាមលំដាប់លម្អិតជាងមុន៖ អ្នកកំណត់ចំនួនតម្លៃ *មិនមែនទទេ* ដែលជួរដេក ឬជួរឈរមួយត្រូវតែមានដើម្បីរក្សាទុក៖\n" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 80 }, "id": "M9dCNMaagRsG", "outputId": "8093713a-54d2-4e54-c73f-4eea315cb6f2", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
12.05.08NaN
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "1 2.0 5.0 8 NaN" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example4.dropna(axis='rows', thresh=3)" ] }, { "cell_type": "markdown", "metadata": { "id": "fmSFnzZegRsG" }, "source": [ "នៅទីនេះ ជួរដើមនិងចុងមួយត្រូវបានដាក់ទៅក្រោម ពីព្រោះវាមានតែពីរតម្លៃមិនទទេប៉ុណ្ណោះ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "mCcxLGyUgRsG" }, "source": [ "### បំពេញតម្លៃ​ទទេ\n", "\n", "ពេលខ្លះ វាអាចមានអត្ថប្រយោជន៍ក្នុងការបំពេញតម្លៃដែលខ្វះដោយតម្លៃដែលអាចមានភាពត្រឹមត្រូវ។ មានបច្ចេកទេសមួយចំនួនសម្រាប់បំពេញតម្លៃទទេ។ វិធីដំបូងគឺប្រើចំណេះដឹងអំពីដែនកំណត់ (ចំណេះដឹងអំពីប្រធានបទដែលទិន្នន័យភ្ជាប់) ដើម្បីប្រមាណតម្លៃដែលខ្វះ។\n", "\n", "អ្នកអាចប្រើ `isnull` ដើម្បីធ្វើការបំពេញនេះនៅទីតាំងដើមបាន ប៉ុន្តែវាអាចពិបាក ជាពិសេសបើអ្នកមានតម្លៃច្រើនដែលត្រូវបំពេញ។ ដោយសារតែនេះគឺជាការងារពេញនិយមក្នុងវិទ្យាសាស្ត្រទិន្នន័យ pandas បានផ្តល់ជូន `fillna` ដែលត្រឡប់រូបមន្តមួយនៃ `Series` ឬ `DataFrame` ដែលមានតម្លៃខ្វះត្រូវបានប្តូរជាមួយតម្លៃដែលអ្នកជ្រើសរើស។ យើងមកបង្កើតឧទាហរណ៍ថ្មីមួយទៀតនៃ `Series` ដើម្បីមើលថាវាធ្វើការដូចម្តេចក្នុងការអនុវត្ត។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "CE8S7louLezV" }, "source": [ "### ទិន្នន័យប្រភេទក្រុម(មិនមែនជាលេខ)\n", "មុនគេ យើងមកពិចារណាអំពីទិន្នន័យមិនមែនជាលេខ។ ក្នុងសំណុំទិន្នន័យ យើងមានជួរឈរដែលមានទិន្នន័យប្រភេទក្រុម។ ឧទាហរណ៍ ភេទ, ត្រឹមត្រូវ ឬ មិនត្រឹមត្រូវ ល។ \n", "\n", "នៅក្នុងករណីភាគច្រើននេះ យើងជំនួសតម្លៃខ្វះដោយ `mode` របស់ជួរឈរ។ បើសិនជាយើងមានចំណុចទិន្នន័យ ១០០ និង ៩០ នាក់បាននិយាយថា ត្រឹមត្រូវ, ៨ នាក់បាននិយាយថា មិនត្រឹមត្រូវ ហើយ ២ នាក់មិនបានបំពេញ។ បន្ទាប់មក យើងអាចបំពេញ ២ នាក់ជាមួយតម្លៃ ត្រឹមត្រូវ ដោយគិតពីជួរឈរសរុប។\n", "\n", "ម្ដងទៀត នៅទីនេះ យើងអាចប្រើចំណេះដឹងផ្នែកដែនដី។ យើងមកពិចារណាឧទាហរណ៍នៃការបំពេញដោយ mode។\n" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 204 }, "id": "MY5faq4yLdpQ", "outputId": "19ab472e-1eed-4de8-f8a7-db2a3af3cb1a" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
012True
134None
256False
378True
4910True
\n", "
" ], "text/plain": [ " 0 1 2\n", "0 1 2 True\n", "1 3 4 None\n", "2 5 6 False\n", "3 7 8 True\n", "4 9 10 True" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fill_with_mode = pd.DataFrame([[1,2,\"True\"],\n", " [3,4,None],\n", " [5,6,\"False\"],\n", " [7,8,\"True\"],\n", " [9,10,\"True\"]])\n", "\n", "fill_with_mode" ] }, { "cell_type": "markdown", "metadata": { "id": "MLAoMQOfNPlA" }, "source": [ "ឥឡូវនេះ សូមយើងស្វែងរកម៉ូដមុនពេលបំពេញតម្លៃ `None` ជាមួយម៉ូដ។\n" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "WKy-9Y2tN5jv", "outputId": "8da9fa16-e08c-447e-dea1-d4b1db2feebf" }, "outputs": [ { "data": { "text/plain": [ "True 3\n", "False 1\n", "Name: 2, dtype: int64" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fill_with_mode[2].value_counts()" ] }, { "cell_type": "markdown", "metadata": { "id": "6iNz_zG_OKrx" }, "source": [ "ដូច្នេះ យើងនឹងជំនួស None ជា True។\n" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "id": "TxPKteRvNPOs" }, "outputs": [], "source": [ "fill_with_mode[2].fillna('True',inplace=True)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 204 }, "id": "tvas7c9_OPWE", "outputId": "ec3c8e44-d644-475e-9e22-c65101965850" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
012True
134True
256False
378True
4910True
\n", "
" ], "text/plain": [ " 0 1 2\n", "0 1 2 True\n", "1 3 4 True\n", "2 5 6 False\n", "3 7 8 True\n", "4 9 10 True" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fill_with_mode" ] }, { "cell_type": "markdown", "metadata": { "id": "SktitLxxOR16" }, "source": [ "ដូចដែលយើងអាចមើលឃើញ តម្លៃ null ត្រូវបានប្តូរជំនួស។ មិនចាំបាច់និយាយថា យើងអាចបានសរសេរអ្វីមួយណាមួយជំនួសឬ `'True'` ហើយវានឹងត្រូវបានប្តូរជំនួសផងដែរ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "heYe1I0dOmQ_" }, "source": [ "### ទិន្នន័យគណនាផ្នែកចំនួន\n", "ឥឡូវនេះ មកដល់ទិន្នន័យគណនាផ្នែកចំនួន។ នៅទីនេះ យើងមានមធ្យោបាយពីរដើម្បីជំនួសតម្លៃចាញ់ខ្វះ៖\n", "\n", "1. ជំនួសជាមួយមេឌៀននៃជួរដេក\n", "2. ជំនួសជាមួយមធ្យមនៃជួរដេក\n", "\n", "យើងជំនួសជាមួយមេឌៀន ក្នុងករណីទិន្នន័យមានការបែកដេកជាមួយតម្លៃខុសៗគ្នា។ នេះសំរាប់មេឌៀនមានភាពរឹងមាំចំពោះតម្លៃខុសៗគ្នា។\n", "\n", "ពេលដែលទិន្នន័យត្រូវបានធម្មតា (normalized) យើងអាចប្រើមធ្យមបាន ព្រោះនៅក្នុងករណីនោះ មធ្យមនិងមេឌៀននឹងមានតម្លៃជិតគ្នា។\n", "\n", "ដំបូង យើងចាប់យកជួរឈរមួយដែលបែងចែកធម្មតា ហើយឲ្យយើងបំពេញតម្លៃខ្វះជាមួយមធ្យមនៃជួរឈរនោះ។\n" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 204 }, "id": "09HM_2feOj5Y", "outputId": "7e309013-9acb-411c-9b06-4de795bbeeff" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
0-2.001
1-1.023
2NaN45
31.067
42.089
\n", "
" ], "text/plain": [ " 0 1 2\n", "0 -2.0 0 1\n", "1 -1.0 2 3\n", "2 NaN 4 5\n", "3 1.0 6 7\n", "4 2.0 8 9" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fill_with_mean = pd.DataFrame([[-2,0,1],\n", " [-1,2,3],\n", " [np.nan,4,5],\n", " [1,6,7],\n", " [2,8,9]])\n", "\n", "fill_with_mean" ] }, { "cell_type": "markdown", "metadata": { "id": "ka7-wNfzSxbx" }, "source": [ "មធ្យមភាគនៃជួរឈរនេះគឺ\n" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "XYtYEf5BSxFL", "outputId": "68a78d18-f0e5-4a9a-a959-2c3676a57c70" }, "outputs": [ { "data": { "text/plain": [ "0.0" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.mean(fill_with_mean[0])" ] }, { "cell_type": "markdown", "metadata": { "id": "oBSRGxKRS39K" }, "source": [ "បំពេញជាមួយค่า​មធ្យម\n" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 204 }, "id": "FzncQLmuS5jh", "outputId": "00f74fff-01f4-4024-c261-796f50f01d2e" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
0-2.001
1-1.023
20.045
31.067
42.089
\n", "
" ], "text/plain": [ " 0 1 2\n", "0 -2.0 0 1\n", "1 -1.0 2 3\n", "2 0.0 4 5\n", "3 1.0 6 7\n", "4 2.0 8 9" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fill_with_mean[0].fillna(np.mean(fill_with_mean[0]),inplace=True)\n", "fill_with_mean" ] }, { "cell_type": "markdown", "metadata": { "id": "CwpVFCrPTC5z" }, "source": [ "ដូចដែលយើងអាចឃើញ តម្លៃដែលបាត់បង់បានត្រូវបានជំនួសដោយមធ្យមភាគរបស់វា។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "jIvF13a1i00Z" }, "source": [ "ឥឡូវនេះ យើងចូរព្យាយាម dataframe មួយផ្សេងទៀត ហើយពេលនេះ យើងនឹងជំនួសតម្លៃ None ជាមួយមិត្ត​រដ្ឋកណ្តាលនៃកូឡុំ។\n" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 204 }, "id": "DA59Bqo3jBYZ", "outputId": "85dae6ec-7394-4c36-fda0-e04769ec4a32" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
0-20.01
1-12.03
20NaN5
316.07
428.09
\n", "
" ], "text/plain": [ " 0 1 2\n", "0 -2 0.0 1\n", "1 -1 2.0 3\n", "2 0 NaN 5\n", "3 1 6.0 7\n", "4 2 8.0 9" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fill_with_median = pd.DataFrame([[-2,0,1],\n", " [-1,2,3],\n", " [0,np.nan,5],\n", " [1,6,7],\n", " [2,8,9]])\n", "\n", "fill_with_median" ] }, { "cell_type": "markdown", "metadata": { "id": "mM1GpXYmjHnc" }, "source": [ "មធ្យមភាគនៃជួរឈរទីពីរគឺ\n" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "uiDy5v3xjHHX", "outputId": "564b6b74-2004-4486-90d4-b39330a64b88" }, "outputs": [ { "data": { "text/plain": [ "4.0" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fill_with_median[1].median()" ] }, { "cell_type": "markdown", "metadata": { "id": "z9PLF75Jj_1s" }, "source": [ "បម្រះដោយម​ធ្យមភាគ\n" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 204 }, "id": "lFKbOxCMkBbg", "outputId": "a8bd18fb-2765-47d4-e5fe-e965f57ed1f4" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
012
0-20.01
1-12.03
204.05
316.07
428.09
\n", "
" ], "text/plain": [ " 0 1 2\n", "0 -2 0.0 1\n", "1 -1 2.0 3\n", "2 0 4.0 5\n", "3 1 6.0 7\n", "4 2 8.0 9" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fill_with_median[1].fillna(fill_with_median[1].median(),inplace=True)\n", "fill_with_median" ] }, { "cell_type": "markdown", "metadata": { "id": "8JtQ53GSkKWC" }, "source": [ "ដូចដែលយើងឃើញ តម្លៃ NaN ត្រូវបានជំនួសដោយតម្លៃមធ្យមកណ្តាលនៃជួរឈរ។\n" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "0ybtWLDdgRsG", "outputId": "b8c238ef-6024-4ee2-be2b-aa1f0fcac61d", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "a 1.0\n", "b NaN\n", "c 2.0\n", "d NaN\n", "e 3.0\n", "dtype: float64" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example5 = pd.Series([1, np.nan, 2, None, 3], index=list('abcde'))\n", "example5" ] }, { "cell_type": "markdown", "metadata": { "id": "yrsigxRggRsH" }, "source": [ "អ្នកអាចបំពេញចន្លោះទទេទាំងអស់ដោយតម្លៃតែមួយបាន ដូចជារាប់ `0`:\n" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "KXMIPsQdgRsH", "outputId": "aeedfa0a-a421-4c2f-cb0d-183ce8f0c91d", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "a 1.0\n", "b 0.0\n", "c 2.0\n", "d 0.0\n", "e 3.0\n", "dtype: float64" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example5.fillna(0)" ] }, { "cell_type": "markdown", "metadata": { "id": "RRlI5f_hkfKe" }, "source": [ "> ចំណុចសំខាន់:\n", "1. ការបំពេញតម្លៃដែលខ្វះគួរត្រូវធ្វើពេលមានទិន្នន័យតិច ឬមានយុទ្ធសាស្រ្តក្នុងការបំពេញទិន្នន័យដែលខ្វះ។\n", "2. ចំណេះដឹងដែនកំណាត់អាចត្រូវប្រើដើម្បីបំពេញតម្លៃដែលខ្វះដោយប្រហាក់ប្រហែលវា។\n", "3. សម្រាប់ទិន្នន័យប្រភេទកាតេហ្គរីភិក, ភាគច្រើនតម្លៃដែលខ្វះត្រូវបានជំនួសជាមួយម៉ូដនៃជួរឈរ។\n", "4. សម្រាប់ទិន្នន័យគណិតវិទ្យា, តម្លៃដែលខ្វះភាគច្រើនត្រូវបានបំពេញជាមួយមធ្យម (សម្រាប់ឃមnormalized datasets) ឬមធ្យមភាគពីរ (median) នៃជួរឈរ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "FI9MmqFJgRsH" }, "source": [ "### អនុវត្តវិជ្ជា:\n" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": true, "id": "af-ezpXdgRsH", "trusted": false }, "outputs": [], "source": [ "# What happens if you try to fill null values with a string, like ''?\n" ] }, { "cell_type": "markdown", "metadata": { "id": "kq3hw1kLgRsI" }, "source": [ "អ្នកអាច **បំពេញតម្លៃ​ទំនេរ** ជាមុខមែន ដោយប្រើតម្លៃត្រឹមត្រូវចុងក្រោយដើម្បីបំពេញតម្លៃទំនេរ៖\n" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "vO3BuNrggRsI", "outputId": "e2bc591b-0b48-4e88-ee65-754f2737c196", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "a 1.0\n", "b 1.0\n", "c 2.0\n", "d 2.0\n", "e 3.0\n", "dtype: float64" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example5.fillna(method='ffill')" ] }, { "cell_type": "markdown", "metadata": { "id": "nDXeYuHzgRsI" }, "source": [ "អ្នកក៏អាច **បំពេញត្រឡប់** ដើម្បីផ្សព្វផ្សាយតម្លៃត្រឹមត្រូវបន្ទាប់ទៅក្រោយត្រឡប់មកដើម្បីបំពេញតម្លៃទទេបានផងដែរ៖\n" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "4M5onHcEgRsI", "outputId": "8f32b185-40dd-4a9f-bd85-54d6b6a414fe", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "a 1.0\n", "b 2.0\n", "c 2.0\n", "d 3.0\n", "e 3.0\n", "dtype: float64" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example5.fillna(method='bfill')" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "id": "MbBzTom5gRsI" }, "source": [ "ដូចដែលអ្នកអាចរើសគំនិតបាន វានៅតែមើលទៅដូចគ្នាជាមួយ DataFrames ប៉ុន្តែអ្នកក៏អាចបញ្ជាក់ `axis` មួយដែលត្រូវបំពេញតម្លៃទទេ។\n" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 142 }, "id": "aRpIvo4ZgRsI", "outputId": "905a980a-a808-4eca-d0ba-224bd7d85955", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
01.0NaN7NaN
12.05.08NaN
2NaN6.09NaN
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 1.0 NaN 7 NaN\n", "1 2.0 5.0 8 NaN\n", "2 NaN 6.0 9 NaN" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example4" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 142 }, "id": "VM1qtACAgRsI", "outputId": "71f2ad28-9b4e-4ff4-f5c3-e731eb489ade", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
01.01.07.07.0
12.05.08.08.0
2NaN6.09.09.0
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 1.0 1.0 7.0 7.0\n", "1 2.0 5.0 8.0 8.0\n", "2 NaN 6.0 9.0 9.0" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example4.fillna(method='ffill', axis=1)" ] }, { "cell_type": "markdown", "metadata": { "id": "ZeMc-I1EgRsI" }, "source": [ "សូមចំណាំថា ពេលដែលមូល្យតម្លៃមុនមិនមានសម្រាប់បំពេញទៅមុខ តម្លៃទទេនោះនឹងនៅតែមិនប្រែប្រួល។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "eeAoOU0RgRsJ" }, "source": [ "### ព្យាយាម:\n" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": true, "id": "e8S-CjW8gRsJ", "trusted": false }, "outputs": [], "source": [ "# What output does example4.fillna(method='bfill', axis=1) produce?\n", "# What about example4.fillna(method='ffill') or example4.fillna(method='bfill')?\n", "# Can you think of a longer code snippet to write that can fill all of the null values in example4?\n" ] }, { "cell_type": "markdown", "metadata": { "id": "YHgy0lIrgRsJ" }, "source": [ "អ្នកអាចមានភាពច្នៃប្រឌិតអំពីវិធីដែលអ្នកប្រើ `fillna` បាន។ ឧទាហរណ៍ មកមើល `example4` ម្តងទៀត ប៉ុន្តេលើកនេះ យើង filling តម្លៃខ្វះជាមួយមធ្យមផ្សំទាំងអស់ក្នុង `DataFrame`:\n" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 142 }, "id": "OtYVErEygRsJ", "outputId": "708b1e67-45ca-44bf-a5ee-8b2de09ece73", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0123
01.05.57NaN
12.05.08NaN
21.56.09NaN
\n", "
" ], "text/plain": [ " 0 1 2 3\n", "0 1.0 5.5 7 NaN\n", "1 2.0 5.0 8 NaN\n", "2 1.5 6.0 9 NaN" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example4.fillna(example4.mean())" ] }, { "cell_type": "markdown", "metadata": { "id": "zpMvCkLSgRsJ" }, "source": [ "សូមស្ដាប់ថា កាលុំនី 3 នៅតែមិនមានតម្លៃ៖ ទិសដៅលំនាំដើមគឺបំពេញតម្លៃតាមជួរដេក។\n", "\n", "> **ចំណាប់អារម្មណ៍៖** មានវិធីជាច្រើនក្នុងការដោះស្រាយតម្លៃខ្វះនៅក្នុងសំណុំទិន្នន័យរបស់អ្នក។ គោលការណ៍ជាក់លាក់ដែលអ្នកប្រើ (បែកចេញ ព្យួរប្រែប្លែង ឬហើយថា វិធីដែលអ្នកប្តូរពួកវា) គួរតែត្រូវបានកំណត់ដោយលក្ខណៈពិសេសនៃទិន្នន័យនោះ។ អ្នកនឹងអភិវឌ្ឍការយល់ដឹងល្អប្រសើរច្រើនពីរបៀបដោះស្រាយតម្លៃខ្វះនៅពេលដែលអ្នកដោះស្រាយ និងទាក់ទងជាមួយសំណុំទិន្នន័យ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "bauDnESIl9FH" }, "source": [ "### ការអ៊ិនកូដទិន្នន័យប្រភេទផ្នែក\n", "\n", "ម៉ូដែលរៀនម៉ាស៊ីនគ្រាន់តែដំណើរការលេខនិងទិន្នន័យគណនាត្រឹមតែ។ វា​នឹងមិន​អាច​បំបែក​ភាពខុសគ្នារវាង បាទ និង ទេ ទេ ប៉ុន្តែវានឹងអាចបំបែកចន្លោះ 0 និង 1 តែប៉ុណ្ណោះ។ ដូច្នេះ បន្ទាប់ពីបំពេញតម្លៃខ្វះ យើងត្រូវតែអ៊ិនកូដទិន្នន័យប្រភេទផ្នែកទៅទ្រង់ទ្រង់លេខសម្រាប់ម៉ូដែលយល់។\n", "\n", "ការអ៊ិនកូដអាចធ្វើបានពីរបៀប។ យើងនឹងពិភាក្សាពួកវាតទៅមុខ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "uDq9SxB7mu5i" }, "source": [ "**ការអ៊ិនកូដស្លាក**\n", "\n", "\n", "ការអ៊ិនកូដស្លាកគឺជាការបំលែងប្រភេទគ្រប់មួយទៅជាលេខ។ ឧទាហរណ៍ មេីលយើងមានទិន្នន័យអ្នកធ្វើដំណើរការយន្តហោះ ហើយមានជួរឈរមួយដែលមានថ្នាក់របស់ពួកគេក្នុងចំណោម ['business class', 'economy class','first class']។ ប្រសិនបើអ៊ិនកូដស្លាកត្រូវបានអនុវត្តលើនេះ វានឹងប្តូរទៅជា [0,1,2]។ មកមេីលឧទាហរណ៍តាមកូដ។ ពីព្រោះយើងនឹងរៀន `scikit-learn` ក្នុងកំណត់ត្រាចេញក្រោយ យើងមិនប្រើវាដោយផ្ទាល់នៅទីនេះទេ។\n" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 235 }, "id": "1vGz7uZyoWHL", "outputId": "9e252855-d193-4103-a54d-028ea7787b34" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
IDclass
010business class
120first class
230economy class
340economy class
450economy class
560business class
\n", "
" ], "text/plain": [ " ID class\n", "0 10 business class\n", "1 20 first class\n", "2 30 economy class\n", "3 40 economy class\n", "4 50 economy class\n", "5 60 business class" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "label = pd.DataFrame([\n", " [10,'business class'],\n", " [20,'first class'],\n", " [30, 'economy class'],\n", " [40, 'economy class'],\n", " [50, 'economy class'],\n", " [60, 'business class']\n", "],columns=['ID','class'])\n", "label" ] }, { "cell_type": "markdown", "metadata": { "id": "IDHnkwTYov-h" }, "source": [ "ដើម្បីអនុវត្តការវិភាគស្លាកនៅជួរឈរទីមួយ យើងត្រូវតែពណ៌នាការបម្លែងពីថ្នាក់នីមួយៗទៅជាចំនួនមួយជាមុនសិន មុនពេលប្ដូរឡើងវិញ។\n" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 235 }, "id": "ZC5URJG3o1ES", "outputId": "aab0f1e7-e0f3-4c14-8459-9f9168c85437" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
IDclass
0100
1202
2301
3401
4501
5600
\n", "
" ], "text/plain": [ " ID class\n", "0 10 0\n", "1 20 2\n", "2 30 1\n", "3 40 1\n", "4 50 1\n", "5 60 0" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class_labels = {'business class':0,'economy class':1,'first class':2}\n", "label['class'] = label['class'].replace(class_labels)\n", "label" ] }, { "cell_type": "markdown", "metadata": { "id": "ftnF-TyapOPt" }, "source": [ "ដូចដែលយើងអាចមើលឃើញ លទ្ធផលផ្ទ keluម្រប់គ្នានឹងអ្វីដែលយើងគិតថានឹងកើតឡើង។ ដូច្នេះ ពេលណាមួយយើងប្រើការបំលែងស្លាក? ការបំលែងស្លាកត្រូវបានប្រើនៅក្នុងករណីណាមួយ ឬទាំងពីរនៃករណីខាងក្រោម៖\n", "1. នៅពេលដែលចំនួនប្រភេទធំ\n", "2. នៅពេលដែលប្រភេទមានលំដាប់។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "eQPAPVwsqWT7" }, "source": [ "**ONE HOT ENCODING**\n", "\n", "ប្រភេទកូដមួយទៀតគឺ One Hot Encoding។ ក្នុងប្រភេទកូដនេះ ប្រភេទនីមួយៗនៃជួរឈរត្រូវបានបន្ថែមជាជួរឈរផ្សេងបង្កើតឡើង ហើយចំណុចទិន្នន័យនិមួយៗនឹងទទួលបានលេខ 0 ឬ 1 ដោយផ្អែកលើថាតើវាមានប្រភេទនោះ។ ដូច្នេះ ប្រសិនបើមានប្រភេទខុសៗគ្នា n ប្រភេទ នោះជួរឈរ n នឹងត្រូវបានបូកបន្ថែមចូលទៅក្នុងតារាងទិន្នន័យ។\n", "\n", "ឧទាហរណ៍ យើងសន្និដ្ឋានថាតែមួយថ្នាក់យន្តហោះដូចគ្នា។ ប្រភេទគឺជា៖ ['business class', 'economy class','first class']។ ដូច្នេះ ប្រសិនបើយើងអនុវត្ត One Hot Encoding ជួរឈរទាំងបីខាងក្រោមនឹងត្រូវបានបន្ថែមទៅក្នុងសំណុំទិន្នន័យ៖ ['class_business class','class_economy class','class_first class']។\n" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 235 }, "id": "ZM0eVh0ArKUL", "outputId": "83238a76-b3a5-418d-c0b6-605b02b6891b" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
IDclass
010business class
120first class
230economy class
340economy class
450economy class
560business class
\n", "
" ], "text/plain": [ " ID class\n", "0 10 business class\n", "1 20 first class\n", "2 30 economy class\n", "3 40 economy class\n", "4 50 economy class\n", "5 60 business class" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "one_hot = pd.DataFrame([\n", " [10,'business class'],\n", " [20,'first class'],\n", " [30, 'economy class'],\n", " [40, 'economy class'],\n", " [50, 'economy class'],\n", " [60, 'business class']\n", "],columns=['ID','class'])\n", "one_hot" ] }, { "cell_type": "markdown", "metadata": { "id": "aVnZ7paDrWmb" }, "source": [ "យើងអនុវត្តការអ៊ិនកូដឯកតាមួយលើជួរឈរទី ១\n" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "id": "RUPxf7egrYKr" }, "outputs": [], "source": [ "one_hot_data = pd.get_dummies(one_hot,columns=['class'])" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 235 }, "id": "TM37pHsFr4ge", "outputId": "7be15f53-79b2-447a-979c-822658339a9e" }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
IDclass_business classclass_economy classclass_first class
010100
120001
230010
340010
450010
560100
\n", "
" ], "text/plain": [ " ID class_business class class_economy class class_first class\n", "0 10 1 0 0\n", "1 20 0 0 1\n", "2 30 0 1 0\n", "3 40 0 1 0\n", "4 50 0 1 0\n", "5 60 1 0 0" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "one_hot_data" ] }, { "cell_type": "markdown", "metadata": { "id": "_zXRLOjXujdA" }, "source": [ "ជួរឈរ​កូដ​ជា​មួយ​តែមួយ​មួយគឺ​មាន​តម្លៃ 0 ឬ 1 ដែល​បញ្ជាក់​ថា​ចំណាត់ថ្នាក់​នោះ​មាន​សម្រាប់​ចំណុច​ទិន្នន័យ​នោះ​ឬ​អត់។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "bDnC4NQOu0qr" }, "source": [ "តើយើងប្រើការវាយលេខ one hot encoding ពេលណា? ការវាយលេខ one hot encoding ត្រូវបានប្រើនៅពេលណាមួយ ឬទាំងពីររឿងខាងក្រោមនេះ៖\n", "\n", "1. ពេលដែលចំនួនប្រភេទនិងទំហំឃ្លាំងទិន្នន័យមានតូច។\n", "2. ពេលដែលប្រភេទទាំងអស់មិនមានលំដាប់ពិសេសណាមួយ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "XnUmci_4uvyu" }, "source": [ "> ពិន្ទុចម្បងដែលគួរចងចាំ៖\n", "1. ការវាយកូដត្រូវបានធ្វើឡើងដើម្បីបំលែងទិន្នន័យដែលមិនមែនជាចំនួនទៅជាទិន្នន័យជាចំនួន។\n", "2. មានប្រភេទការវាយកូដពីរប្រើ៖ ការវាយកូដស្លាក និងការវាយកូដ One Hot ដែលទាំងពីរអាចអនុវត្តបានដោយផ្អែកលើតម្រូវការរបស់សំណុំទិន្នន័យ។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "K8UXOJYRgRsJ" }, "source": [ "## លុបយកទិន្នន័យមេរៀនមកវិញ\n", "\n", "> **គោលបំណងការសិក្សា៖** នៅចុងបញ្ចប់នៃផ្នែកបន្ទាប់នេះ អ្នកគួរតែមានភាពស៑កស្អិតក្នុងការបញ្ជាក់ និងលុបចោលតម្លៃមេរៀនពី DataFrames។\n", "\n", "ក្រៅពីទិន្នន័យដែលខ្វះ អ្នកនឹងជួបប្រទៈនឹងទិន្នន័យមេរៀនជាញឹកញាប់ក្នុងឯកសារទិន្នន័យពិតប្រាកដ។ ជាថាស័ក្តិ pandas ផ្តល់នូវវិធីងាយស្រួលក្នុងការស្វែងរក និងលុបចោលបញ្ចូលព័ត៌មានមេរៀន។\n" ] }, { "cell_type": "markdown", "metadata": { "id": "qrEG-Wa0gRsJ" }, "source": [ "### ការកំណត់អត្តសញ្ញាណចម្លង: `duplicated`\n", "\n", "អ្នកអាចរកឃើញតម្លៃចម្លងបានយ៉ាងងាយស្រួលដោយប្រើវិធីសាស្ត្រ `duplicated` ក្នុង pandas ដែលផ្តល់ជាមាសប៊៊ូលបង្ហាញថាតើចំណងជើងមួយនៅក្នុង `DataFrame` ជាចម្លងនៃចំណងជើងមួយដែលមានមុនធ្លាប់ឬអត់។ តោះបង្កើត `DataFrame` មួយផ្សេងទៀតដើម្បីមើលវានៅក្នុងសកម្មភាព។\n" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 204 }, "id": "ZLu6FEnZgRsJ", "outputId": "376512d1-d842-4db1-aea3-71052aeeecaf", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
lettersnumbers
0A1
1B2
2A1
3B3
4B3
\n", "
" ], "text/plain": [ " letters numbers\n", "0 A 1\n", "1 B 2\n", "2 A 1\n", "3 B 3\n", "4 B 3" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example6 = pd.DataFrame({'letters': ['A','B'] * 2 + ['B'],\n", " 'numbers': [1, 2, 1, 3, 3]})\n", "example6" ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "cIduB5oBgRsK", "outputId": "3da27b3d-4d69-4e1d-bb52-0af21bae87f2", "trusted": false }, "outputs": [ { "data": { "text/plain": [ "0 False\n", "1 False\n", "2 True\n", "3 False\n", "4 True\n", "dtype: bool" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example6.duplicated()" ] }, { "cell_type": "markdown", "metadata": { "id": "0eDRJD4SgRsK" }, "source": [ "### ការលុបចោលចម្លងទិន្នន័យ៖ `drop_duplicates`\n", "`drop_duplicates` គឺត្រឹមតែបម្លងទិន្នន័យមួយច្បាស់សម្រាប់ដែលមានតម្លៃ `duplicated` ទាំងអស់ជា `False` ៖\n" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 142 }, "id": "w_YPpqIqgRsK", "outputId": "ac66bd2f-8671-4744-87f5-8b8d96553dea", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
lettersnumbers
0A1
1B2
3B3
\n", "
" ], "text/plain": [ " letters numbers\n", "0 A 1\n", "1 B 2\n", "3 B 3" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example6.drop_duplicates()" ] }, { "cell_type": "markdown", "metadata": { "id": "69AqoCZAgRsK" }, "source": [ "ទាំង `duplicated` និង `drop_duplicates` តែងតែគិតគូសបញ្ជាក់ទៅលើព្រមគ្រប់ជួរឈរ ប៉ុន្តែអ្នកអាចបញ្ជាក់ថាពួកវាគ្រោងតែពិនិត្យតែផ្នែកខ្លះនៃជួរឈរនៅក្នុង `DataFrame` របស់អ្នកបាន៖\n" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 111 }, "id": "BILjDs67gRsK", "outputId": "ef6dcc08-db8b-4352-c44e-5aa9e2bec0d3", "trusted": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
lettersnumbers
0A1
1B2
\n", "
" ], "text/plain": [ " letters numbers\n", "0 A 1\n", "1 B 2" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "example6.drop_duplicates(['letters'])" ] }, { "cell_type": "markdown", "metadata": { "id": "GvX4og1EgRsL" }, "source": [ "> **សេចក្តីសង្ខេប:** ការដកចេញទិន្នន័យមួយរំពាស់គឺជាផ្នែកសំខាន់របស់គម្រោងវិទ្យាសាស្ត្រទិន្នន័យភាគច្រើន។ ទិន្នន័យមួយរំពាស់អាចផ្លាស់ប្តូរប្រាក់លទ្ធផលនៃការវិភាគរបស់អ្នក និងផ្តល់លទ្ធផលមិនត្រឹមត្រូវជូនអ្នក!\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ការត្រួតពិនិត្យគុណភាពទិន្នន័យនៅក្នុងពិភពជាក់ស្តែង\n", "\n", "> **គោលដៅការសិក្សា:** នៅចុងផ្នែកនេះ អ្នកគួរតែមានភាពស្រួលក្នុងការសម្រេចឲ្យបានថា ពេលឃើញបញ្ហាគុណភាពទិន្នន័យជាក់ស្តែងដូចជា តម្លៃប្រភេទមានការមិនសំរបសំរួល តម្លៃលេខវិភាគអាសកម្ម (outliers) និងអ្វីដែលធ្វើរចនាសម្ព័ន្ធទិន្នន័យត្រូវបញ្ចេញតាមបែបផែននៃការភច្ចរម្រៃ។\n", "\n", "ទោះបីជាតម្លៃខ្វះនិងកំណត់ត្រាការចម្លងជាក់លាក់គឺជាបញ្ហាទូទៅក៏ដោយ មូលដ្ឋានទិន្នន័យនៅក្នុងពិភពជាក់ស្តែងភាគច្រើនផ្ទុកបញ្ហាលំបាកជាងនេះ៖\n", "\n", "1. **តម្លៃប្រភេទដែលមិនសំរបសំរួល**៖ ប្រភេទដដែលដែលមានការវាយអក្សរផ្សេងៗគ្នា (ដូចជា \"USA\", \"U.S.A\", \"United States\")\n", "2. **តម្លៃលេខវិភាគអសកម្ម**៖ គន្លងកំណត់ខ្ពស់ឬទាបខ្លាំងដែលបង្ហាញកំហុសបញ្ចូលទិន្នន័យ (ដូចជា អាយុ = 999)\n", "3. **ជួរដូចគ្នា قريب**៖ កំណត់ត្រាដែលតំណាងឲ្យអEntityដូចគ្នា តែមានការប្រែប្រួលតិចតួច\n", "\n", "ចូរយើងស្វែងយល់ពីវិធីសាស្រ្តក្នុងការរកឃើញ និងដោះស្រាយបញ្ហាទាំងនេះ។\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### បង្កើតឯកសារទិន្នន័យ \"ស្អំណោច\" ឧទាហរណ៍\n", "\n", "ជំហ៊តដំបូង មកបង្កើតឯកសារទិន្នន័យឧទាហរណ៍មួយដែលមានប្រភេទបញ្ហាដែលយើងជួបប្រទៈជាញឹកញាប់ក្នុងទិន្នន័យពិត៖\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import numpy as np\n", "\n", "# Create a sample dataset with quality issues\n", "dirty_data = pd.DataFrame({\n", " 'customer_id': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\n", " 'name': ['John Smith', 'Jane Doe', 'John Smith', 'Bob Johnson', \n", " 'Alice Williams', 'Charlie Brown', 'John Smith', 'Eva Martinez',\n", " 'Bob Johnson', 'Diana Prince', 'Frank Castle', 'Alice Williams'],\n", " 'age': [25, 32, 25, 45, 28, 199, 25, 31, 45, 27, -5, 28],\n", " 'country': ['USA', 'UK', 'U.S.A', 'Canada', 'USA', 'United Kingdom',\n", " 'United States', 'Mexico', 'canada', 'USA', 'UK', 'usa'],\n", " 'purchase_amount': [100.50, 250.00, 105.00, 320.00, 180.00, 90.00,\n", " 102.00, 275.00, 325.00, 195.00, 410.00, 185.00]\n", "})\n", "\n", "print(\"Sample 'Dirty' Dataset:\")\n", "print(dirty_data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1. ការសម្គាល់តម្លៃចំណាត់ថ្នាក់មិនត្រឹមត្រូវ\n", "\n", "សូមដាក់ចំណាំថា​កូឡុំ `country` មានការបង្ហាញច្រើនប្រភេទសម្រាប់ប្រទេសដដែល។ តោះយើងសម្គាល់ពីភាពមិនសមរម្យទាំងនេះ៖\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Check unique values in the country column\n", "print(\"Unique country values:\")\n", "print(dirty_data['country'].unique())\n", "print(f\"\\nTotal unique values: {dirty_data['country'].nunique()}\")\n", "\n", "# Count occurrences of each variation\n", "print(\"\\nValue counts:\")\n", "print(dirty_data['country'].value_counts())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### ការធ្វើឱ្យតម្លៃប្រភេទសរុបស្មើគ្នា\n", "\n", "យើងអាចបង្កើតការចងក្រងដើម្បីធ្វើឱ្យតម្លៃទាំងនេះស្មើគ្នា។ វិធីសាមញ្ញមួយ​គឺបំលែងទៅជាតួអក្សរតូច ហើយបង្កើតវចនានុក្រមចងក្រង:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create a standardization mapping\n", "country_mapping = {\n", " 'usa': 'USA',\n", " 'u.s.a': 'USA',\n", " 'united states': 'USA',\n", " 'uk': 'UK',\n", " 'united kingdom': 'UK',\n", " 'canada': 'Canada',\n", " 'mexico': 'Mexico'\n", "}\n", "\n", "# Standardize the country column\n", "dirty_data['country_clean'] = dirty_data['country'].str.lower().map(country_mapping)\n", "\n", "print(\"Before standardization:\")\n", "print(dirty_data['country'].value_counts())\n", "print(\"\\nAfter standardization:\")\n", "print(dirty_data[['country_clean']].value_counts())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**ជម្រើសមួយផ្សេងទៀត៖ ការប្រើប្រាស់ការចំរូងស្រដៀងគ្នា**\n", "\n", "សម្រាប់ករណីស្មុគស្មាញជាងនេះ យើងអាចប្រើការចំរូងខ្សែអក្សរស្រដៀងគ្នាជាមួយបណ្ណាល័យ `rapidfuzz` ដើម្បីរកឃើញខ្សែអក្សរស្រដៀងគ្នា secara otomatis:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " from rapidfuzz import process, fuzz\n", "except ImportError:\n", " print(\"rapidfuzz is not installed. Please install it with 'pip install rapidfuzz' to use fuzzy matching.\")\n", " process = None\n", " fuzz = None\n", "\n", "# Get unique countries\n", "unique_countries = dirty_data['country'].unique()\n", "\n", "# For each country, find similar matches\n", "if process is not None and fuzz is not None:\n", " print(\"Finding similar country names (similarity > 70%):\")\n", " for country in unique_countries:\n", " matches = process.extract(country, unique_countries, scorer=fuzz.ratio, limit=3)\n", " # Filter matches with similarity > 70 and not identical\n", " similar = [m for m in matches if m[1] > 70 and m[0] != country]\n", " if similar:\n", " print(f\"\\n'{country}' is similar to:\")\n", " for match, score, _ in similar:\n", " print(f\" - '{match}' (similarity: {score}%)\")\n", "else:\n", " print(\"Skipping fuzzy matching because rapidfuzz is not available.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. ការរកឃើញតម្លៃចំនួនអសកម្ម (Outliers)\n", "\n", "មើលទៅកូឡাম `age` យើងមានតម្លៃខុសប្រក្រតីមួយចំនួនដូចជា 199 និង -5។ អ្នកមកប្រើវិធីសាស្រ្តស្ថិតិដើម្បីរកឃើញអត្រាចេញនេះ។\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Display basic statistics\n", "print(\"Age column statistics:\")\n", "print(dirty_data['age'].describe())\n", "\n", "# Identify impossible values using domain knowledge\n", "print(\"\\nRows with impossible age values (< 0 or > 120):\")\n", "impossible_ages = dirty_data[(dirty_data['age'] < 0) | (dirty_data['age'] > 120)]\n", "print(impossible_ages[['customer_id', 'name', 'age']])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### ការប្រើវិធីសាស្រ្ត IQR (ចន្លោះចំណែកបួន) \n", "\n", "វិធីសាស្រ្ត IQR គឺជាយុទ្ធសាស្រ្តស្ថិតិរឹងមាំសម្រាប់ការរកចេញចំណុចបម្រែង ដែលមានភាពមិនទំនាក់ទំនងច្រើនទៅតម្លៃខ្ពស់ខ្នាញ់:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Calculate IQR for age (excluding impossible values)\n", "valid_ages = dirty_data[(dirty_data['age'] >= 0) & (dirty_data['age'] <= 120)]['age']\n", "\n", "Q1 = valid_ages.quantile(0.25)\n", "Q3 = valid_ages.quantile(0.75)\n", "IQR = Q3 - Q1\n", "\n", "# Define outlier bounds\n", "lower_bound = Q1 - 1.5 * IQR\n", "upper_bound = Q3 + 1.5 * IQR\n", "\n", "print(f\"IQR-based outlier bounds for age: [{lower_bound:.2f}, {upper_bound:.2f}]\")\n", "\n", "# Identify outliers\n", "age_outliers = dirty_data[(dirty_data['age'] < lower_bound) | (dirty_data['age'] > upper_bound)]\n", "print(f\"\\nRows with age outliers:\")\n", "print(age_outliers[['customer_id', 'name', 'age']])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### ការប្រើវិធាន Z-Score\n", "\n", "វិធីសាស្រ្ត Z-score កំណត់អ្នកចេញពីដែនលើមូលដ្ឋានលើវិធីសាស្រ្តធម្មតាម៉ាប់ពីម៉ូតុងមធ្យម:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " from scipy import stats\n", "except ImportError:\n", " print(\"scipy is required for Z-score calculation. Please install it with 'pip install scipy' and rerun this cell.\")\n", "else:\n", " # Calculate Z-scores for age, handling NaN values\n", " age_nonan = dirty_data['age'].dropna()\n", " zscores = np.abs(stats.zscore(age_nonan))\n", " dirty_data['age_zscore'] = np.nan\n", " dirty_data.loc[age_nonan.index, 'age_zscore'] = zscores\n", "\n", " # Typically, Z-score > 3 indicates an outlier\n", " print(\"Rows with age Z-score > 3:\")\n", " zscore_outliers = dirty_data[dirty_data['age_zscore'] > 3]\n", " print(zscore_outliers[['customer_id', 'name', 'age', 'age_zscore']])\n", "\n", " # Clean up the temporary column\n", " dirty_data = dirty_data.drop('age_zscore', axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### ការដោះស្រាយចំណុចចម្លែក\n", "\n", "បន្ទាប់ពីរកឃើញ រួចហើយ ចំណុចចម្លែកអាចត្រូវបានដោះស្រាយដោយវិធីខ្លះៗដូចខាងក្រោម៖\n", "1. **លុបចោល**៖ លុបជួរដេកមានចំណុចចម្លែក (បើវាជាកំហុស)\n", "2. **កំណត់កម្រិត**៖ ផ្លាស់ទីជាមួយតម្លៃកំណត់ស្វែង\n", "3. **ជំនួសជាមួយ NaN**៖ គិតថាជាទិន្នន័យខ្វះ ហើយប្រើបច្ចេកទេសបញ្ចូលតម្លៃបាត់បង់\n", "4. **រក្សាទុក**៖ ប្រសិនបើវាជាតម្លៃអញ្ញើញស្រឡាយត្រឹមត្រូវ\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create a cleaned version by replacing impossible ages with NaN\n", "dirty_data['age_clean'] = dirty_data['age'].apply(\n", " lambda x: np.nan if (x < 0 or x > 120) else x\n", ")\n", "\n", "print(\"Age column before and after cleaning:\")\n", "print(dirty_data[['customer_id', 'name', 'age', 'age_clean']])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3. ការរកឃើញជួរដូចគ្នា​ជិតៗ\n", "\n", "សូមកត់សម្គាល់ថាឯកសារទិន្នន័យរបស់យើងមានការចុះបញ្ជីច្រើនសម្រាប់ \"John Smith\" ដែលមានតម្លៃខុសគ្នារបៀបស្រាល។ យើងនឹងស្វែងរកចម្លើយដែលអាចជាអត្រាចម្លងដោយផ្អែកលើភាពស្រដៀងនៃឈ្មោះ។\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# First, let's look at exact name matches (ignoring extra whitespace)\n", "dirty_data['name_normalized'] = dirty_data['name'].str.strip().str.lower()\n", "\n", "print(\"Checking for duplicate names:\")\n", "duplicate_names = dirty_data[dirty_data.duplicated(['name_normalized'], keep=False)]\n", "print(duplicate_names.sort_values('name_normalized')[['customer_id', 'name', 'age', 'country']])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### ការស្វែងរកចម្លើយជិតដូចគ្នាដោយប្រើការភាពរសជា\n", "\n", "សម្រាប់ការស្វែងរកចម្លើយតែបន្តិចទៅមុខជាងនេះ យើងអាចប្រើការភាពរសជាដើម្បីស្វែងរកឈ្មោះដែលស្រដៀងគ្នា:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " from rapidfuzz import process, fuzz\n", "\n", " # Function to find potential duplicates\n", " def find_near_duplicates(df, column, threshold=90):\n", " \"\"\"\n", " Find near-duplicate entries in a column using fuzzy matching.\n", " \n", " Parameters:\n", " - df: DataFrame\n", " - column: Column name to check for duplicates\n", " - threshold: Similarity threshold (0-100)\n", " \n", " Returns: List of potential duplicate groups\n", " \"\"\"\n", " values = df[column].unique()\n", " duplicate_groups = []\n", " checked = set()\n", " \n", " for value in values:\n", " if value in checked:\n", " continue\n", " \n", " # Find similar values\n", " matches = process.extract(value, values, scorer=fuzz.ratio, limit=len(values))\n", " similar = [m[0] for m in matches if m[1] >= threshold]\n", " \n", " if len(similar) > 1:\n", " duplicate_groups.append(similar)\n", " checked.update(similar)\n", " \n", " return duplicate_groups\n", "\n", " # Find near-duplicate names\n", " duplicate_groups = find_near_duplicates(dirty_data, 'name', threshold=90)\n", "\n", " print(\"Potential duplicate groups:\")\n", " for i, group in enumerate(duplicate_groups, 1):\n", " print(f\"\\nGroup {i}:\")\n", " for name in group:\n", " matching_rows = dirty_data[dirty_data['name'] == name]\n", " print(f\" '{name}': {len(matching_rows)} occurrence(s)\")\n", " for _, row in matching_rows.iterrows():\n", " print(f\" - Customer {row['customer_id']}: age={row['age']}, country={row['country']}\")\n", "except ImportError:\n", " print(\"rapidfuzz is not installed. Skipping fuzzy matching for near-duplicates.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### ការដោះស្រាយចម្លងមួយៗ\n", "\n", "ពេលដែលបានសម្គាល់ហើយ អ្នកត្រូវសម្រេចចិត្តពីវិធីដែលត្រូវដោះស្រាយចម្លងមួយៗៈ\n", "1. **រក្សាទុកករណីជាលំដាប់ដំបូង**: ប្រើ `drop_duplicates(keep='first')`\n", "2. **រក្សាទុកករណីជាលំដាប់ចុងក្រោយ**: ប្រើ `drop_duplicates(keep='last')`\n", "3. **សរុបព័ត៌មាន**: បញ្ចូលព័ត៌មានពីជួរដេកចម្លង\n", "4. **ពិនិត្យដោយដៃ**: សញ្ញាសម្រាប់ការពិនិត្យដោយមនុស្ស\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Example: Remove duplicates based on normalized name, keeping first occurrence\n", "cleaned_data = dirty_data.drop_duplicates(subset=['name_normalized'], keep='first')\n", "\n", "print(f\"Original dataset: {len(dirty_data)} rows\")\n", "print(f\"After removing name duplicates: {len(cleaned_data)} rows\")\n", "print(f\"Removed: {len(dirty_data) - len(cleaned_data)} duplicate rows\")\n", "\n", "print(\"\\nCleaned dataset:\")\n", "print(cleaned_data[['customer_id', 'name', 'age', 'country_clean']])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### សេចក្ដីសង្ខេប៖ ស៊ុមដំណើរការសម្អាតទិន្នន័យពេញលេញ\n", "\n", "មកធ្វើវាជាស៊ុមដំណើរការសម្អាតទិន្នន័យទាំងមូលគ្នា៖\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def clean_dataset(df):\n", " \"\"\"\n", " Comprehensive data cleaning function.\n", " \"\"\"\n", " # Create a copy to avoid modifying the original\n", " cleaned = df.copy()\n", " \n", " # 1. Standardize categorical values (country)\n", " country_mapping = {\n", " 'usa': 'USA', 'u.s.a': 'USA', 'united states': 'USA',\n", " 'uk': 'UK', 'united kingdom': 'UK',\n", " 'canada': 'Canada', 'mexico': 'Mexico'\n", " }\n", " cleaned['country'] = cleaned['country'].str.lower().map(country_mapping)\n", " \n", " # 2. Clean abnormal age values\n", " cleaned['age'] = cleaned['age'].apply(\n", " lambda x: np.nan if (x < 0 or x > 120) else x\n", " )\n", " \n", " # 3. Remove near-duplicate names (normalize whitespace)\n", " cleaned['name'] = cleaned['name'].str.strip()\n", " cleaned = cleaned.drop_duplicates(subset=['name'], keep='first')\n", " \n", " return cleaned\n", "\n", "# Apply the cleaning pipeline\n", "final_cleaned_data = clean_dataset(dirty_data)\n", "\n", "print(\"Before cleaning:\")\n", "print(f\" Rows: {len(dirty_data)}\")\n", "print(f\" Unique countries: {dirty_data['country'].nunique()}\")\n", "print(f\" Invalid ages: {((dirty_data['age'] < 0) | (dirty_data['age'] > 120)).sum()}\")\n", "\n", "print(\"\\nAfter cleaning:\")\n", "print(f\" Rows: {len(final_cleaned_data)}\")\n", "print(f\" Unique countries: {final_cleaned_data['country'].nunique()}\")\n", "print(f\" Invalid ages: {((final_cleaned_data['age'] < 0) | (final_cleaned_data['age'] > 120)).sum()}\")\n", "\n", "print(\"\\nCleaned dataset:\")\n", "print(final_cleaned_data[['customer_id', 'name', 'age', 'country', 'purchase_amount']])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 🎯 លំហាត់ប្រកួត\n", "\n", "ឥឡូវនេះជំពាក់អ្នក! ខាងក្រោមនេះជាឈុតទិន្នន័យថ្មីមួយដែលមានបញ្ហាគុណភាពច្រើន។ តើអ្នកអាច៖\n", "\n", "1. កំណត់បញ្ហាទាំងអស់នៅក្នុងជួរនេះ\n", "2. សរសេរកូដដើម្បីសម្អាតបញ្ហា​នីមួយៗ\n", "3. បន្ថែមជួរដែលបានសម្អាតទៅកាន់សំណុំទិន្នន័យ\n", "\n", "នេះជាទិន្នន័យដែលមានបញ្ហា៖\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# New problematic row\n", "new_row = pd.DataFrame({\n", " 'customer_id': [13],\n", " 'name': [' Diana Prince '], # Extra whitespace\n", " 'age': [250], # Impossible age\n", " 'country': ['U.S.A.'], # Inconsistent format\n", " 'purchase_amount': [150.00]\n", "})\n", "\n", "print(\"New row to clean:\")\n", "print(new_row)\n", "\n", "# TODO: Your code here to clean this row\n", "# Hints:\n", "# 1. Strip whitespace from the name\n", "# 2. Check if the name is a duplicate (Diana Prince already exists)\n", "# 3. Handle the impossible age value\n", "# 4. Standardize the country name\n", "\n", "# Example solution (uncomment and modify as needed):\n", "# new_row_cleaned = new_row.copy()\n", "# new_row_cleaned['name'] = new_row_cleaned['name'].str.strip()\n", "# new_row_cleaned['age'] = np.nan # Invalid age\n", "# new_row_cleaned['country'] = 'USA' # Standardized\n", "# print(\"\\nCleaned row:\")\n", "# print(new_row_cleaned)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### ចំណុចសំខាន់ៗ\n", "\n", "1. **ប្រភេទដែលមិនស្របគ្នា** ជារឿងធម្មតានៅក្នុងទិន្នន័យពិភពលោកពិត។ តែងតែពិនិត្យតម្លៃពិសេសៗ ហើយស្តង់ដាឌ័រអ្នកប្រើប្រាស់ដោយប្រើផែនទីឬការប្រៀបធៀបដូចជា fuzzy matching។\n", "\n", "2. **ចំណុចលើស** អាចមានឥទ្ធិពលយ៉ាងខ្លាំងលើការវិភាគរបស់អ្នក។ ប្រើចំណេះដឹងស្រុកជាមួយវិធីសាស្រ្តស្ថិតិបទ (IQR, Z-score) ដើម្បីរកតួអង្គទាំងនេះ។\n", "\n", "3. **ចម្លងប្រហែល** គឺកាន់តែពិបាករកឃើញជាងចម្លងត្រឹមត្រូវ។ គិតពីការប្រើ fuzzy matching និងធម្មតាតម្លៃទិន្នន័យ (ធ្វើអក្សរតូច, ដកចេញដ៏ចាល់លើកន្លែងទំហឹង) ដើម្បីរកឃើញវា។\n", "\n", "4. **ការសម្អាតទិន្នន័យគឺជាការធ្វើជាការបន្តបន្ទាប់**។ អ្នកប្រហែលត្រូវការប្រើបច្ចេកទេសជាច្រើន ហើយពិនិត្យលទ្ធផលមុនពេលបញ្ចប់សំណុំទិន្នន័យសម្អាតរបស់អ្នក។\n", "\n", "5. **ឯកសារសេចក្តីសម្រេចរបស់អ្នក**។ រក្សាតាមដាននូវជំហានសម្អាតដែលអ្នកបានអនុវត្ត និងហេតុផល, ព្រោះវាសំខាន់សម្រាប់ការបង្កើតឡើងវិញ និងភាពច្បាស់លាស់។\n", "\n", "> **ការអនុវត្តដ៏ល្អបំផុត:** តែងតែរក្សាចម្លងនៃទិន្នន័យ \"ស្អាត\" ដើមរបស់អ្នក។ មិនត្រូវបិទលើឯកសារទិន្នន័យប្រតិបត្តិរបស់អ្នកទេ - បង្កើតកំណែស្អាតដែលមានការកំណត់ឈ្មោះច្បាស់លាស់ដូចជា `data_cleaned.csv` ។\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n\n\n**ការបដិសេធ**៖ \nឯកសារនេះត្រូវបានបម្លែងភាសាដោយប្រើសេវាកម្មបកប្រែ AI [Co-op Translator](https://github.com/Azure/co-op-translator)។ ខណៈពេលដែលយើងខំប្រឹងប្រែងឲ្យបានត្រឹមត្រូវ សូមយល់ថាការបកប្រែដោយស្វ័យប្រវត្តិអាចមានកំហុសឬភាពមិនត្រឹមត្រូវ។ ឯកសារដើមជាភាសាមាតុភូមិគួរត្រូវបានគេពិចារណាថាជា ប្រភពផ្លូវការជាផ្លូវការ។ សម្រាប់ព័ត៌មានដ៏សំខាន់ សូមផ្តល់លទ្ធភាពការបកប្រែដោយមនុស្សជំនាញ។ យើងមិនទទួលខុសត្រូវចំពោះការយល់ច្រឡំ ឬការបកស្រាយខុសប្រកបដោយការប្រើប្រាស់ការបកប្រែនេះទេ។\n\n" ] } ], "metadata": { "anaconda-cloud": {}, "colab": { "name": "notebook.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.5.4" } }, "nbformat": 4, "nbformat_minor": 0 }