{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "rQ8UhzFpgRra" }, "source": [ "# Chuẩn bị Dữ liệu\n", "\n", "[Notebook gốc từ *Khoa học Dữ liệu: Giới thiệu về Machine Learning cho Khoa học Dữ liệu Python và Machine Learning Studio của Lee Stott*](https://github.com/leestott/intro-Datascience/blob/master/Course%20Materials/4-Cleaning_and_Manipulating-Reference.ipynb)\n", "\n", "## Khám phá thông tin `DataFrame`\n", "\n", "> **Mục tiêu học tập:** Sau khi hoàn thành phần này, bạn sẽ cảm thấy thoải mái khi tìm kiếm thông tin tổng quát về dữ liệu được lưu trữ trong pandas DataFrames.\n", "\n", "Khi bạn đã tải dữ liệu của mình vào pandas, rất có thể nó sẽ ở dạng `DataFrame`. Tuy nhiên, nếu tập dữ liệu trong `DataFrame` của bạn có 60.000 hàng và 400 cột, làm thế nào để bạn bắt đầu hiểu được những gì mình đang làm việc? May mắn thay, pandas cung cấp một số công cụ tiện lợi để nhanh chóng xem thông tin tổng quan về một `DataFrame`, bên cạnh việc xem qua một vài hàng đầu tiên và cuối cùng.\n", "\n", "Để khám phá chức năng này, chúng ta sẽ nhập thư viện scikit-learn của Python và sử dụng một tập dữ liệu mang tính biểu tượng mà mọi nhà khoa học dữ liệu đều đã thấy hàng trăm lần: tập dữ liệu *Iris* của nhà sinh học người Anh Ronald Fisher, được sử dụng trong bài báo năm 1936 của ông \"Sử dụng các phép đo đa chiều trong các vấn đề phân loại học\":\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", "Chúng ta đã tải bộ dữ liệu Iris vào biến `iris_df`. Trước khi đi sâu vào dữ liệu, sẽ rất hữu ích nếu biết số lượng điểm dữ liệu chúng ta có và kích thước tổng thể của bộ dữ liệu. Việc xem xét khối lượng dữ liệu mà chúng ta đang xử lý là rất quan trọng.\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": [ "Vì vậy, chúng ta đang xử lý 150 hàng và 4 cột dữ liệu. Mỗi hàng đại diện cho một điểm dữ liệu và mỗi cột đại diện cho một đặc điểm duy nhất liên quan đến khung dữ liệu. Nói cách khác, có 150 điểm dữ liệu, mỗi điểm chứa 4 đặc điểm.\n", "\n", "`shape` ở đây là một thuộc tính của khung dữ liệu chứ không phải là một hàm, đó là lý do tại sao nó không kết thúc bằng một cặp dấu ngoặc đơn.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "d3AZKs0PinGP" }, "source": [ "### `DataFrame.columns`\n", "Bây giờ, chúng ta hãy xem xét 4 cột dữ liệu. Mỗi cột thực sự đại diện cho điều gì? Thuộc tính `columns` sẽ cung cấp cho chúng ta tên của các cột trong 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": [ "Như chúng ta có thể thấy, có bốn (4) cột. Thuộc tính `columns` cho chúng ta biết tên của các cột và về cơ bản không có gì khác. Thuộc tính này trở nên quan trọng khi chúng ta muốn xác định các đặc điểm mà một tập dữ liệu chứa.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "2UTlvkjmgRrs" }, "source": [ "### `DataFrame.info`\n", "Số lượng dữ liệu (được cung cấp bởi thuộc tính `shape`) và tên của các đặc điểm hoặc cột (được cung cấp bởi thuộc tính `columns`) cho chúng ta một số thông tin về tập dữ liệu. Bây giờ, chúng ta sẽ muốn tìm hiểu sâu hơn về tập dữ liệu. Hàm `DataFrame.info()` rất hữu ích cho việc này.\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": [ "Từ đây, chúng ta có thể rút ra một vài quan sát: \n", "1. Kiểu dữ liệu của mỗi cột: Trong tập dữ liệu này, tất cả dữ liệu đều được lưu trữ dưới dạng số thực dấu phẩy động 64-bit. \n", "2. Số lượng giá trị không null: Xử lý các giá trị null là một bước quan trọng trong việc chuẩn bị dữ liệu. Việc này sẽ được xử lý sau trong notebook. \n" ] }, { "cell_type": "markdown", "metadata": { "id": "IYlyxbpWFEF4" }, "source": [ "### DataFrame.describe()\n", "Giả sử chúng ta có rất nhiều dữ liệu số trong tập dữ liệu của mình. Các phép tính thống kê đơn biến như giá trị trung bình, trung vị, tứ phân vị, v.v. có thể được thực hiện trên từng cột riêng lẻ. Hàm `DataFrame.describe()` cung cấp cho chúng ta một bản tóm tắt thống kê của các cột số trong tập dữ liệu.\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": [ "Đầu ra ở trên hiển thị tổng số điểm dữ liệu, giá trị trung bình, độ lệch chuẩn, giá trị nhỏ nhất, tứ phân vị dưới (25%), trung vị (50%), tứ phân vị trên (75%) và giá trị lớn nhất của mỗi cột.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "-lviAu99gRrv" }, "source": [ "### `DataFrame.head`\n", "Với tất cả các hàm và thuộc tính đã đề cập ở trên, chúng ta đã có cái nhìn tổng quan về tập dữ liệu. Chúng ta biết có bao nhiêu điểm dữ liệu, có bao nhiêu đặc trưng, kiểu dữ liệu của từng đặc trưng và số lượng giá trị không null cho mỗi đặc trưng.\n", "\n", "Bây giờ là lúc xem xét chính dữ liệu. Hãy xem vài hàng đầu tiên (vài điểm dữ liệu đầu tiên) của `DataFrame` của chúng ta trông như thế nào:\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": [ "Như đầu ra ở đây, chúng ta có thể thấy năm (5) mục của tập dữ liệu. Nếu chúng ta nhìn vào chỉ mục ở bên trái, chúng ta phát hiện ra rằng đây là năm hàng đầu tiên.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "oj7GkrTdgRry" }, "source": [ "### Bài tập:\n", "\n", "Từ ví dụ được đưa ra ở trên, rõ ràng rằng, theo mặc định, `DataFrame.head` trả về năm hàng đầu tiên của một `DataFrame`. Trong ô mã dưới đây, bạn có thể tìm ra cách hiển thị nhiều hơn năm hàng không?\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", "Một cách khác để xem dữ liệu là từ cuối (thay vì từ đầu). Đối lập với `DataFrame.head` là `DataFrame.tail`, chức năng này trả về năm hàng cuối cùng của một `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": [ "Trong thực tế, việc có thể dễ dàng kiểm tra vài hàng đầu tiên hoặc vài hàng cuối cùng của một `DataFrame` rất hữu ích, đặc biệt khi bạn đang tìm kiếm các giá trị ngoại lệ trong các tập dữ liệu có thứ tự.\n", "\n", "Tất cả các hàm và thuộc tính được trình bày ở trên với sự hỗ trợ của các ví dụ mã đều giúp chúng ta có cái nhìn và cảm nhận về dữ liệu.\n", "\n", "> **Điểm rút ra:** Chỉ cần nhìn vào siêu dữ liệu về thông tin trong một DataFrame hoặc vài giá trị đầu tiên và cuối cùng của nó, bạn có thể có ngay một ý tưởng về kích thước, hình dạng và nội dung của dữ liệu mà bạn đang xử lý.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "TvurZyLSDxq_" }, "source": [ "### Dữ Liệu Thiếu\n", "Hãy cùng tìm hiểu về dữ liệu thiếu. Dữ liệu thiếu xảy ra khi không có giá trị nào được lưu trữ trong một số cột.\n", "\n", "Hãy lấy một ví dụ: giả sử ai đó rất quan tâm đến cân nặng của mình và không điền vào trường cân nặng trong một khảo sát. Khi đó, giá trị cân nặng của người đó sẽ bị thiếu.\n", "\n", "Phần lớn thời gian, trong các tập dữ liệu thực tế, giá trị thiếu thường xuyên xảy ra.\n", "\n", "**Cách Pandas xử lý dữ liệu thiếu**\n", "\n", "Pandas xử lý giá trị thiếu theo hai cách. Cách đầu tiên bạn đã thấy trong các phần trước: `NaN`, hoặc Not a Number (Không phải là một số). Đây thực chất là một giá trị đặc biệt thuộc về đặc tả số học dấu phẩy động IEEE và nó chỉ được sử dụng để biểu thị các giá trị dấu phẩy động bị thiếu.\n", "\n", "Đối với các giá trị thiếu không phải là số dấu phẩy động, pandas sử dụng đối tượng `None` của Python. Mặc dù có thể gây nhầm lẫn khi bạn gặp hai loại giá trị khác nhau nhưng đều biểu thị cùng một ý nghĩa, có những lý do lập trình hợp lý cho lựa chọn thiết kế này. Trên thực tế, cách tiếp cận này cho phép pandas cung cấp một sự cân bằng tốt cho phần lớn các trường hợp. Tuy nhiên, cả `None` và `NaN` đều có những hạn chế mà bạn cần lưu ý liên quan đến cách chúng có thể được sử dụng.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "lOHqUlZFgRr5" }, "source": [ "### `None`: dữ liệu thiếu không phải kiểu float\n", "Vì `None` xuất phát từ Python, nó không thể được sử dụng trong các mảng NumPy và pandas không có kiểu dữ liệu `'object'`. Hãy nhớ rằng, các mảng NumPy (và các cấu trúc dữ liệu trong pandas) chỉ có thể chứa một loại dữ liệu duy nhất. Đây chính là điều mang lại sức mạnh vượt trội cho chúng trong công việc xử lý dữ liệu và tính toán quy mô lớn, nhưng đồng thời cũng hạn chế sự linh hoạt của chúng. Các mảng như vậy phải được chuyển đổi sang kiểu dữ liệu “mẫu số chung thấp nhất,” tức là kiểu dữ liệu có thể bao gồm tất cả mọi thứ trong mảng. Khi `None` xuất hiện trong mảng, điều đó có nghĩa là bạn đang làm việc với các đối tượng Python.\n", "\n", "Để thấy điều này trong thực tế, hãy xem xét mảng ví dụ sau (lưu ý `dtype` của nó):\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": [ "Thực tế của việc nâng cấp kiểu dữ liệu đi kèm với hai tác động phụ. Đầu tiên, các thao tác sẽ được thực hiện ở cấp độ mã Python được diễn giải thay vì mã NumPy được biên dịch. Về cơ bản, điều này có nghĩa là bất kỳ thao tác nào liên quan đến `Series` hoặc `DataFrames` có chứa `None` sẽ chậm hơn. Mặc dù bạn có thể không nhận thấy sự giảm hiệu suất này, nhưng đối với các tập dữ liệu lớn, nó có thể trở thành vấn đề.\n", "\n", "Tác động phụ thứ hai xuất phát từ tác động đầu tiên. Vì `None` về cơ bản kéo `Series` hoặc `DataFrame`s trở lại thế giới của Python thuần túy, việc sử dụng các hàm tổng hợp của NumPy/pandas như `sum()` hoặc `min()` trên các mảng chứa giá trị ``None`` thường sẽ gây ra lỗi:\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": [] }, { "cell_type": "markdown", "metadata": { "id": "pWvVHvETgRr9" }, "source": [ "### `NaN`: giá trị float bị thiếu\n", "\n", "Khác với `None`, NumPy (và do đó cả pandas) hỗ trợ `NaN` để thực hiện các phép toán và ufuncs nhanh, theo vector. Tin xấu là bất kỳ phép toán số học nào thực hiện trên `NaN` đều luôn cho ra kết quả là `NaN`. Ví dụ:\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": [ "Tin tốt: các phép tổng hợp chạy trên các mảng có `NaN` trong đó không gây ra lỗi. Tin xấu: kết quả không phải lúc nào cũng hữu ích:\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": [] }, { "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": [] }, { "cell_type": "markdown", "metadata": { "id": "kj6EKdsAgRsA" }, "source": [ "### `NaN` và `None`: giá trị null trong pandas\n", "\n", "Mặc dù `NaN` và `None` có thể hoạt động hơi khác nhau, pandas vẫn được thiết kế để xử lý chúng một cách thay thế cho nhau. Để hiểu rõ hơn, hãy xem xét một `Series` các số nguyên:\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": [] }, { "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": [ "Trong quá trình nâng cấp kiểu dữ liệu để đảm bảo tính đồng nhất trong `Series` và `DataFrame`, pandas sẽ dễ dàng chuyển đổi giá trị thiếu giữa `None` và `NaN`. Vì đặc điểm thiết kế này, bạn có thể nghĩ về `None` và `NaN` như hai dạng khác nhau của \"null\" trong pandas. Thực tế, một số phương thức cốt lõi mà bạn sẽ sử dụng để xử lý giá trị thiếu trong pandas phản ánh ý tưởng này qua tên gọi của chúng:\n", "\n", "- `isnull()`: Tạo một mặt nạ Boolean chỉ ra các giá trị thiếu\n", "- `notnull()`: Ngược lại với `isnull()`\n", "- `dropna()`: Trả về phiên bản dữ liệu đã được lọc\n", "- `fillna()`: Trả về một bản sao của dữ liệu với các giá trị thiếu được điền hoặc ước tính\n", "\n", "Đây là những phương thức quan trọng cần nắm vững và làm quen, vì vậy hãy cùng tìm hiểu chi tiết từng phương thức.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "Yh5ifd9FgRsB" }, "source": [ "### Phát hiện giá trị null\n", "\n", "Bây giờ chúng ta đã hiểu tầm quan trọng của các giá trị thiếu, chúng ta cần phát hiện chúng trong tập dữ liệu trước khi xử lý.\n", "\n", "Cả `isnull()` và `notnull()` đều là các phương pháp chính để phát hiện dữ liệu null. Cả hai đều trả về mặt nạ Boolean trên dữ liệu của bạn.\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": [ "Hãy nhìn kỹ vào kết quả. Có điều gì khiến bạn ngạc nhiên không? Mặc dù `0` là một giá trị số học rỗng, nó vẫn là một số nguyên hợp lệ và pandas xử lý nó như vậy. `''` thì tinh tế hơn một chút. Mặc dù chúng ta đã sử dụng nó trong Phần 1 để biểu thị một chuỗi rỗng, nhưng nó vẫn là một đối tượng chuỗi và không được pandas coi là một biểu diễn của giá trị null.\n", "\n", "Bây giờ, hãy đảo ngược tình huống và sử dụng các phương pháp này theo cách giống như bạn sẽ sử dụng chúng trong thực tế. Bạn có thể sử dụng các mặt nạ Boolean trực tiếp làm chỉ mục của ``Series`` hoặc ``DataFrame``, điều này có thể hữu ích khi bạn muốn làm việc với các giá trị bị thiếu (hoặc có mặt) riêng lẻ.\n", "\n", "Nếu chúng ta muốn tổng số giá trị bị thiếu, chúng ta chỉ cần thực hiện phép cộng trên mặt nạ được tạo bởi phương thức `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": [] }, { "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": [ "**Điểm chính**: Cả hai phương thức `isnull()` và `notnull()` đều tạo ra kết quả tương tự khi bạn sử dụng chúng trong DataFrame: chúng hiển thị kết quả và chỉ mục của những kết quả đó, điều này sẽ giúp bạn rất nhiều khi bạn xử lý dữ liệu của mình.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "BvnoojWsgRr4" }, "source": [ "### Xử lý dữ liệu thiếu\n", "\n", "> **Mục tiêu học tập:** Sau khi hoàn thành phần này, bạn sẽ biết cách và thời điểm thay thế hoặc loại bỏ các giá trị null trong DataFrames.\n", "\n", "Các mô hình Machine Learning không thể tự xử lý dữ liệu thiếu. Vì vậy, trước khi đưa dữ liệu vào mô hình, chúng ta cần xử lý các giá trị thiếu này.\n", "\n", "Cách xử lý dữ liệu thiếu mang theo những sự đánh đổi tinh tế, có thể ảnh hưởng đến phân tích cuối cùng và kết quả thực tế.\n", "\n", "Có hai cách chính để xử lý dữ liệu thiếu:\n", "\n", "1. Loại bỏ hàng chứa giá trị thiếu\n", "2. Thay thế giá trị thiếu bằng một giá trị khác\n", "\n", "Chúng ta sẽ thảo luận cả hai phương pháp này cùng với ưu và nhược điểm của chúng một cách chi tiết.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "3VaYC1TvgRsD" }, "source": [ "### Loại bỏ giá trị null\n", "\n", "Số lượng dữ liệu chúng ta đưa vào mô hình có ảnh hưởng trực tiếp đến hiệu suất của nó. Loại bỏ giá trị null có nghĩa là chúng ta đang giảm số lượng điểm dữ liệu, và do đó giảm kích thước của tập dữ liệu. Vì vậy, nên loại bỏ các hàng có giá trị null khi tập dữ liệu khá lớn.\n", "\n", "Một trường hợp khác có thể là một hàng hoặc cột nào đó có rất nhiều giá trị bị thiếu. Khi đó, chúng có thể bị loại bỏ vì chúng không mang lại nhiều giá trị cho phân tích của chúng ta do phần lớn dữ liệu bị thiếu ở hàng/cột đó.\n", "\n", "Ngoài việc xác định các giá trị bị thiếu, pandas cung cấp một cách tiện lợi để loại bỏ giá trị null từ `Series` và `DataFrame`. Để thấy điều này trong thực tế, hãy quay lại `example3`. Hàm `DataFrame.dropna()` giúp loại bỏ các hàng có giá trị null.\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": [ "Lưu ý rằng điều này sẽ giống như kết quả của bạn từ `example3[example3.notnull()]`. Sự khác biệt ở đây là, thay vì chỉ lập chỉ mục trên các giá trị đã được che, `dropna` đã loại bỏ những giá trị bị thiếu khỏi `Series` `example3`.\n", "\n", "Vì DataFrame có hai chiều, chúng cung cấp nhiều tùy chọn hơn để loại bỏ dữ liệu.\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": [ "(Bạn có nhận thấy rằng pandas đã chuyển đổi hai cột thành kiểu float để phù hợp với các giá trị `NaN` không?)\n", "\n", "Bạn không thể xóa một giá trị đơn lẻ từ một `DataFrame`, vì vậy bạn phải xóa toàn bộ hàng hoặc cột. Tùy thuộc vào những gì bạn đang làm, bạn có thể muốn chọn một trong hai cách, và do đó pandas cung cấp cho bạn tùy chọn cho cả hai. Vì trong khoa học dữ liệu, các cột thường đại diện cho biến số và các hàng đại diện cho quan sát, bạn có khả năng cao sẽ xóa các hàng dữ liệu; cài đặt mặc định của `dropna()` là xóa tất cả các hàng chứa bất kỳ giá trị null nào:\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": [ "Nếu cần thiết, bạn có thể loại bỏ các giá trị NA từ các cột. Sử dụng `axis=1` để làm như vậy:\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": [ "Lưu ý rằng điều này có thể loại bỏ rất nhiều dữ liệu mà bạn có thể muốn giữ lại, đặc biệt là trong các tập dữ liệu nhỏ. Vậy nếu bạn chỉ muốn loại bỏ các hàng hoặc cột chứa một số hoặc thậm chí tất cả các giá trị null thì sao? Bạn có thể chỉ định các thiết lập đó trong `dropna` với các tham số `how` và `thresh`.\n", "\n", "Mặc định, `how='any'` (nếu bạn muốn tự kiểm tra hoặc xem phương thức này có các tham số nào khác, hãy chạy `example4.dropna?` trong một ô mã). Ngoài ra, bạn có thể chỉ định `how='all'` để chỉ loại bỏ các hàng hoặc cột chứa toàn bộ giá trị null. Hãy mở rộng ví dụ `DataFrame` của chúng ta để xem điều này hoạt động như thế nào trong bài tập tiếp theo.\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": [ "> Những điểm chính: \n", "1. Loại bỏ các giá trị null chỉ là ý tưởng tốt nếu tập dữ liệu đủ lớn. \n", "2. Có thể loại bỏ toàn bộ hàng hoặc cột nếu phần lớn dữ liệu của chúng bị thiếu. \n", "3. Phương thức `DataFrame.dropna(axis=)` hỗ trợ loại bỏ các giá trị null. Tham số `axis` xác định liệu sẽ loại bỏ hàng hay cột. \n", "4. Tham số `how` cũng có thể được sử dụng. Mặc định, nó được đặt là `any`. Vì vậy, nó chỉ loại bỏ những hàng/cột chứa bất kỳ giá trị null nào. Tham số này có thể được đặt là `all` để chỉ định rằng chúng ta sẽ chỉ loại bỏ những hàng/cột mà tất cả các giá trị đều là null. \n" ] }, { "cell_type": "markdown", "metadata": { "id": "oXXSfQFHgRsF" }, "source": [] }, { "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": [ "Tham số `thresh` cung cấp cho bạn khả năng kiểm soát chi tiết hơn: bạn đặt số lượng giá trị *không null* mà một hàng hoặc cột cần phải có để được giữ lại:\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": [ "Ở đây, hàng đầu tiên và hàng cuối cùng đã bị loại bỏ, vì chúng chỉ chứa hai giá trị không null.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "mCcxLGyUgRsG" }, "source": [ "### Điền giá trị null\n", "\n", "Đôi khi việc điền các giá trị thiếu bằng những giá trị có thể hợp lệ là điều hợp lý. Có một vài kỹ thuật để điền giá trị null. Kỹ thuật đầu tiên là sử dụng Kiến Thức Chuyên Môn (kiến thức về chủ đề mà tập dữ liệu dựa trên) để ước lượng các giá trị bị thiếu.\n", "\n", "Bạn có thể sử dụng `isnull` để làm điều này trực tiếp, nhưng điều đó có thể tốn công, đặc biệt nếu bạn có nhiều giá trị cần điền. Vì đây là một nhiệm vụ rất phổ biến trong khoa học dữ liệu, pandas cung cấp `fillna`, trả về một bản sao của `Series` hoặc `DataFrame` với các giá trị bị thiếu được thay thế bằng giá trị bạn chọn. Hãy tạo một ví dụ khác về `Series` để xem cách hoạt động này trong thực tế.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "CE8S7louLezV" }, "source": [ "### Dữ liệu phân loại (Không phải số)\n", "Đầu tiên, hãy xem xét dữ liệu không phải số. Trong các tập dữ liệu, chúng ta có các cột chứa dữ liệu phân loại. Ví dụ: Giới tính, Đúng hoặc Sai, v.v.\n", "\n", "Trong hầu hết các trường hợp này, chúng ta thay thế các giá trị bị thiếu bằng `mode` của cột. Giả sử, chúng ta có 100 điểm dữ liệu, trong đó 90 điểm là Đúng, 8 điểm là Sai và 2 điểm không được điền. Khi đó, chúng ta có thể điền 2 điểm bị thiếu bằng Đúng, dựa trên toàn bộ cột.\n", "\n", "Một lần nữa, ở đây chúng ta có thể sử dụng kiến thức chuyên môn. Hãy xem xét một ví dụ về việc điền bằng 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": [] }, { "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": [] }, { "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": [ "Như chúng ta có thể thấy, giá trị null đã được thay thế. Không cần phải nói, chúng ta có thể đã viết bất kỳ thứ gì thay cho `'True'` và nó sẽ được thay thế.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "heYe1I0dOmQ_" }, "source": [ "### Dữ liệu Số\n", "Bây giờ, chúng ta sẽ nói về dữ liệu số. Ở đây, có hai cách phổ biến để thay thế giá trị bị thiếu:\n", "\n", "1. Thay thế bằng Trung vị của hàng\n", "2. Thay thế bằng Giá trị trung bình của hàng\n", "\n", "Chúng ta thay thế bằng Trung vị trong trường hợp dữ liệu bị lệch với các giá trị ngoại lai. Điều này là do trung vị không bị ảnh hưởng bởi các giá trị ngoại lai.\n", "\n", "Khi dữ liệu đã được chuẩn hóa, chúng ta có thể sử dụng giá trị trung bình, vì trong trường hợp này, giá trị trung bình và trung vị sẽ khá gần nhau.\n", "\n", "Đầu tiên, hãy lấy một cột có phân phối chuẩn và điền giá trị bị thiếu bằng giá trị trung bình của cột đó.\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": [ "Giá trị trung bình của cột là\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": [] }, { "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": [ "Như chúng ta có thể thấy, giá trị bị thiếu đã được thay thế bằng giá trị trung bình của nó.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "jIvF13a1i00Z" }, "source": [ "Bây giờ hãy thử một dataframe khác, và lần này chúng ta sẽ thay thế các giá trị None bằng giá trị trung vị của cột.\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": [ "Trung vị của cột thứ hai là\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": [] }, { "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": [ "Như chúng ta có thể thấy, giá trị NaN đã được thay thế bằng giá trị trung vị của cột\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": [ "Bạn có thể điền tất cả các mục trống bằng một giá trị duy nhất, chẳng hạn như `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": [ "> Những điểm chính cần lưu ý:\n", "1. Việc điền giá trị thiếu nên được thực hiện khi dữ liệu còn ít hoặc khi có chiến lược để điền vào các giá trị thiếu.\n", "2. Kiến thức chuyên môn có thể được sử dụng để điền giá trị thiếu bằng cách ước lượng chúng.\n", "3. Đối với dữ liệu phân loại, thường thì các giá trị thiếu được thay thế bằng giá trị mode của cột.\n", "4. Đối với dữ liệu số, các giá trị thiếu thường được điền bằng giá trị trung bình (đối với các tập dữ liệu đã được chuẩn hóa) hoặc giá trị trung vị của các cột.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "FI9MmqFJgRsH" }, "source": [] }, { "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": [] }, { "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": [ "Bạn cũng có thể **back-fill** để truyền giá trị hợp lệ tiếp theo ngược lại để điền vào một giá trị null:\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": [ "Như bạn có thể đoán, điều này hoạt động tương tự với DataFrames, nhưng bạn cũng có thể chỉ định một `axis` để điền các giá trị null:\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": [ "Lưu ý rằng khi không có giá trị trước đó để điền tiếp, giá trị null sẽ được giữ nguyên.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "eeAoOU0RgRsJ" }, "source": [] }, { "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": [ "Bạn có thể sáng tạo về cách sử dụng `fillna`. Ví dụ, hãy xem lại `example4`, nhưng lần này hãy điền các giá trị bị thiếu bằng giá trị trung bình của tất cả các giá trị trong `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": [ "Lưu ý rằng cột 3 vẫn chưa có giá trị: hướng mặc định là điền giá trị theo hàng.\n", "\n", "> **Điểm cần nhớ:** Có nhiều cách để xử lý giá trị thiếu trong tập dữ liệu của bạn. Chiến lược cụ thể mà bạn sử dụng (loại bỏ, thay thế, hoặc thậm chí cách bạn thay thế) nên được quyết định bởi đặc điểm cụ thể của dữ liệu đó. Bạn sẽ phát triển cảm giác tốt hơn về cách xử lý giá trị thiếu khi bạn làm việc và tương tác nhiều hơn với các tập dữ liệu.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "bauDnESIl9FH" }, "source": [ "### Mã hóa Dữ liệu Phân loại\n", "\n", "Các mô hình học máy chỉ xử lý được các con số và bất kỳ dạng dữ liệu số nào. Chúng không thể phân biệt giữa \"Yes\" và \"No\", nhưng có thể phân biệt giữa 0 và 1. Vì vậy, sau khi điền các giá trị bị thiếu, chúng ta cần mã hóa dữ liệu phân loại thành một dạng số để mô hình có thể hiểu được.\n", "\n", "Việc mã hóa có thể được thực hiện theo hai cách. Chúng ta sẽ thảo luận về chúng ngay sau đây.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "uDq9SxB7mu5i" }, "source": [ "**MÃ HÓA NHÃN**\n", "\n", "Mã hóa nhãn về cơ bản là chuyển đổi mỗi danh mục thành một số. Ví dụ, giả sử chúng ta có một tập dữ liệu về hành khách hàng không và có một cột chứa hạng ghế của họ trong số các hạng sau ['business class', 'economy class', 'first class']. Nếu thực hiện mã hóa nhãn trên cột này, nó sẽ được chuyển đổi thành [0,1,2]. Hãy cùng xem một ví dụ qua đoạn mã. Vì chúng ta sẽ học `scikit-learn` trong các notebook sắp tới, nên ở đây chúng ta sẽ không sử dụng nó.\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": [ "Để thực hiện mã hóa nhãn trên cột đầu tiên, chúng ta phải đầu tiên mô tả một ánh xạ từ mỗi lớp sang một số, trước khi thay thế\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": [ "Như chúng ta có thể thấy, kết quả đầu ra khớp với những gì chúng ta dự đoán. Vậy, khi nào chúng ta sử dụng mã hóa nhãn? Mã hóa nhãn được sử dụng trong một hoặc cả hai trường hợp sau: \n", "1. Khi số lượng danh mục lớn \n", "2. Khi các danh mục có thứ tự. \n" ] }, { "cell_type": "markdown", "metadata": { "id": "eQPAPVwsqWT7" }, "source": [ "**MÃ HÓA ONE HOT**\n", "\n", "Một loại mã hóa khác là Mã Hóa One Hot. Trong loại mã hóa này, mỗi danh mục của cột sẽ được thêm vào như một cột riêng biệt và mỗi điểm dữ liệu sẽ nhận giá trị 0 hoặc 1 dựa trên việc nó có chứa danh mục đó hay không. Vì vậy, nếu có n danh mục khác nhau, n cột sẽ được thêm vào dataframe.\n", "\n", "Ví dụ, hãy lấy ví dụ về các hạng ghế máy bay. Các danh mục là: ['business class', 'economy class', 'first class']. Vì vậy, nếu chúng ta thực hiện mã hóa one hot, ba cột sau sẽ được thêm vào tập dữ liệu: ['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": [ "Hãy thực hiện mã hóa one hot trên cột đầu tiên\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": [ "Mỗi cột được mã hóa one-hot chứa 0 hoặc 1, xác định liệu danh mục đó có tồn tại cho điểm dữ liệu đó hay không.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "bDnC4NQOu0qr" }, "source": [ "Khi nào chúng ta sử dụng one hot encoding? One hot encoding được sử dụng trong một hoặc cả hai trường hợp sau:\n", "\n", "1. Khi số lượng danh mục và kích thước của tập dữ liệu nhỏ.\n", "2. Khi các danh mục không tuân theo thứ tự cụ thể nào.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "XnUmci_4uvyu" }, "source": [ "> Những điểm chính cần ghi nhớ: \n", "1. Mã hóa được thực hiện để chuyển đổi dữ liệu không phải số thành dữ liệu số. \n", "2. Có hai loại mã hóa: Mã hóa nhãn (Label encoding) và Mã hóa One Hot (One Hot encoding), cả hai đều có thể được thực hiện dựa trên yêu cầu của tập dữ liệu. \n" ] }, { "cell_type": "markdown", "metadata": { "id": "K8UXOJYRgRsJ" }, "source": [ "## Loại bỏ dữ liệu trùng lặp\n", "\n", "> **Mục tiêu học tập:** Sau khi hoàn thành phần này, bạn sẽ tự tin trong việc xác định và loại bỏ các giá trị trùng lặp từ DataFrames.\n", "\n", "Ngoài dữ liệu bị thiếu, bạn thường sẽ gặp dữ liệu trùng lặp trong các tập dữ liệu thực tế. May mắn thay, pandas cung cấp một cách dễ dàng để phát hiện và loại bỏ các mục trùng lặp.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "qrEG-Wa0gRsJ" }, "source": [ "### Xác định các giá trị trùng lặp: `duplicated`\n", "\n", "Bạn có thể dễ dàng phát hiện các giá trị trùng lặp bằng phương pháp `duplicated` trong pandas, phương pháp này trả về một mặt nạ Boolean cho biết liệu một mục trong `DataFrame` có phải là bản sao của một mục trước đó hay không. Hãy tạo một ví dụ `DataFrame` khác để xem cách hoạt động của nó.\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": [ "### Loại bỏ các giá trị trùng lặp: `drop_duplicates`\n", "`drop_duplicates` đơn giản trả về một bản sao của dữ liệu mà tất cả các giá trị `duplicated` là `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": [ "Cả `duplicated` và `drop_duplicates` mặc định xem xét tất cả các cột nhưng bạn có thể chỉ định rằng chúng chỉ kiểm tra một tập hợp con các cột trong `DataFrame` của bạn:\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": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Tuyên bố miễn trừ trách nhiệm**: \nTài liệu này đã được dịch bằng dịch vụ dịch thuật AI [Co-op Translator](https://github.com/Azure/co-op-translator). Mặc dù chúng tôi cố gắng đảm bảo độ chính xác, xin lưu ý rằng các bản dịch tự động có thể chứa lỗi hoặc không chính xác. Tài liệu gốc bằng ngôn ngữ bản địa nên được coi là nguồn tham khảo chính thức. Đối với các thông tin quan trọng, chúng tôi khuyến nghị sử dụng dịch vụ dịch thuật chuyên nghiệp từ con người. Chúng tôi không chịu trách nhiệm cho bất kỳ sự hiểu lầm hoặc diễn giải sai nào phát sinh từ việc sử dụng bản dịch này.\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" }, "coopTranslator": { "original_hash": "8533b3a2230311943339963fc7f04c21", "translation_date": "2025-09-02T08:19:07+00:00", "source_file": "2-Working-With-Data/08-data-preparation/notebook.ipynb", "language_code": "vi" } }, "nbformat": 4, "nbformat_minor": 0 }