{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "rQ8UhzFpgRra" }, "source": [ "# Paghahanda ng Data\n", "\n", "[Orihinal na Notebook mula sa *Data Science: Introduction to Machine Learning for Data Science Python and Machine Learning Studio ni Lee Stott*](https://github.com/leestott/intro-Datascience/blob/master/Course%20Materials/4-Cleaning_and_Manipulating-Reference.ipynb)\n", "\n", "## Paggalugad ng impormasyon ng `DataFrame`\n", "\n", "> **Layunin ng pag-aaral:** Sa pagtatapos ng bahaging ito, dapat kang maging komportable sa paghahanap ng pangkalahatang impormasyon tungkol sa data na nakaimbak sa pandas DataFrames.\n", "\n", "Kapag na-load mo na ang iyong data sa pandas, malamang na ito ay nasa isang `DataFrame`. Gayunpaman, kung ang data set sa iyong `DataFrame` ay may 60,000 na mga hilera at 400 na mga kolum, paano mo sisimulan ang pag-unawa sa kung ano ang iyong pinagtatrabahuhan? Sa kabutihang-palad, ang pandas ay nagbibigay ng ilang maginhawang kasangkapan upang mabilis na makita ang pangkalahatang impormasyon tungkol sa isang `DataFrame` bukod pa sa unang ilang at huling ilang mga hilera.\n", "\n", "Upang galugarin ang kakayahang ito, mag-iimport tayo ng Python scikit-learn library at gagamit ng isang iconic na dataset na nakita na ng bawat data scientist nang daan-daang beses: ang *Iris* dataset ng British biologist na si Ronald Fisher na ginamit sa kanyang papel noong 1936 na \"The use of multiple measurements in taxonomic problems\":\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", "Na-load na natin ang Iris Dataset sa variable na `iris_df`. Bago tayo sumisid sa data, mahalagang malaman ang bilang ng mga datapoints na mayroon tayo at ang kabuuang laki ng dataset. Kapaki-pakinabang na tingnan ang dami ng data na ating pinagtatrabahuhan.\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": [ "Kaya, mayroon tayong 150 na hanay at 4 na kolum ng datos. Ang bawat hanay ay kumakatawan sa isang datapoint at ang bawat kolum ay kumakatawan sa isang tampok na nauugnay sa data frame. Kaya't sa madaling salita, mayroong 150 datapoints na naglalaman ng tig-4 na tampok bawat isa.\n", "\n", "Ang `shape` dito ay isang katangian ng dataframe at hindi isang function, kaya hindi ito nagtatapos sa pares ng mga panaklong.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "d3AZKs0PinGP" }, "source": [ "### `DataFrame.columns`\n", "Ngayon, tingnan natin ang 4 na column ng data. Ano ang eksaktong kinakatawan ng bawat isa sa kanila? Ang `columns` na attribute ay magbibigay sa atin ng mga pangalan ng mga column sa 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": [ "Tulad ng nakikita natin, mayroong apat(4) na kolum. Ang `columns` na katangian ay nagsasabi sa atin ng pangalan ng mga kolum at wala nang iba pa. Ang katangiang ito ay nagiging mahalaga kapag nais nating tukuyin ang mga tampok na nilalaman ng isang dataset.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "2UTlvkjmgRrs" }, "source": [ "### `DataFrame.info`\n", "Ang dami ng datos (ibinibigay ng `shape` attribute) at ang pangalan ng mga tampok o kolum (ibinibigay ng `columns` attribute) ay nagbibigay ng impormasyon tungkol sa dataset. Ngayon, nais nating mas suriin ang dataset. Ang `DataFrame.info()` function ay napaka-kapaki-pakinabang para dito.\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": [ "Mula rito, makakagawa tayo ng ilang obserbasyon: \n", "1. Ang Uri ng Data ng bawat column: Sa dataset na ito, lahat ng data ay nakaimbak bilang 64-bit floating-point numbers. \n", "2. Bilang ng mga Non-Null na halaga: Ang paghawak sa mga null na halaga ay isang mahalagang hakbang sa paghahanda ng data. Ito ay tatalakayin sa susunod na bahagi ng notebook. \n" ] }, { "cell_type": "markdown", "metadata": { "id": "IYlyxbpWFEF4" }, "source": [ "### DataFrame.describe()\n", "Halimbawa, mayroon tayong maraming numerikal na datos sa ating dataset. Ang mga unibaryong kalkulasyong estadistikal tulad ng mean, median, quartiles, at iba pa ay maaaring gawin sa bawat kolum nang paisa-isa. Ang `DataFrame.describe()` na function ay nagbibigay sa atin ng estadistikal na buod ng mga numerikal na kolum ng isang 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": [ "Ang output sa itaas ay nagpapakita ng kabuuang bilang ng mga data point, mean, standard deviation, minimum, lower quartile (25%), median (50%), upper quartile (75%), at ang maximum na halaga ng bawat column.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "-lviAu99gRrv" }, "source": [ "### `DataFrame.head`\n", "Sa lahat ng mga nabanggit na function at attribute, nakuha na natin ang pangkalahatang pananaw sa dataset. Alam natin kung ilang data points ang naroon, kung ilang features ang mayroon, ang uri ng data ng bawat feature, at ang bilang ng mga non-null na halaga para sa bawat feature.\n", "\n", "Ngayon, oras na para tingnan ang mismong data. Tingnan natin kung ano ang hitsura ng unang ilang row (ang unang ilang data points) ng ating `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": [ "Makikita natin dito sa output ang limang (5) entries ng dataset. Kung titingnan natin ang index sa kaliwa, malalaman natin na ito ang unang limang hanay.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "oj7GkrTdgRry" }, "source": [ "### Ehersisyo:\n", "\n", "Mula sa halimbawang ibinigay sa itaas, malinaw na, sa default, ang `DataFrame.head` ay nagbabalik ng unang limang hanay ng isang `DataFrame`. Sa code cell sa ibaba, kaya mo bang alamin kung paano ipakita ang higit sa limang hanay?\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", "Isa pang paraan ng pagtingin sa datos ay mula sa dulo (sa halip na sa simula). Ang kabaligtaran ng `DataFrame.head` ay `DataFrame.tail`, na nagbabalik ng huling limang hanay ng isang `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": [ "Sa praktika, kapaki-pakinabang na madaling masuri ang unang ilang hanay o ang huling ilang hanay ng isang `DataFrame`, lalo na kapag naghahanap ka ng mga outlier sa mga nakaayos na dataset.\n", "\n", "Ang lahat ng mga function at attribute na ipinakita sa itaas gamit ang mga halimbawa ng code ay tumutulong sa atin na magkaroon ng ideya at pakiramdam tungkol sa datos.\n", "\n", "> **Punto:** Kahit sa simpleng pagtingin lamang sa metadata tungkol sa impormasyon sa isang DataFrame o sa unang at huling ilang halaga nito, maaari kang agad magkaroon ng ideya tungkol sa laki, hugis, at nilalaman ng datos na iyong hinahawakan.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "TvurZyLSDxq_" }, "source": [ "### Nawawalang Data\n", "Tuklasin natin ang tungkol sa nawawalang data. Ang nawawalang data ay nangyayari kapag walang halaga ang nakaimbak sa ilang mga column.\n", "\n", "Halimbawa: sabihin nating may isang tao na masyadong maingat sa kanyang timbang at hindi pinupunan ang field ng timbang sa isang survey. Sa ganitong kaso, ang halaga ng timbang para sa taong iyon ay magiging nawawala.\n", "\n", "Kadalasan, sa mga dataset sa totoong mundo, madalas na may mga nawawalang halaga.\n", "\n", "**Paano Hinahandle ng Pandas ang Nawawalang Data**\n", "\n", "Hinahandle ng Pandas ang nawawalang data sa dalawang paraan. Ang una ay nakita mo na sa mga nakaraang seksyon: `NaN`, o Not a Number. Ito ay isang espesyal na halaga na bahagi ng IEEE floating-point specification at ginagamit lamang upang ipakita ang nawawalang floating-point na mga halaga.\n", "\n", "Para sa nawawalang mga halaga maliban sa floats, ginagamit ng pandas ang Python na object na `None`. Bagama't maaaring nakakalito na makatagpo ng dalawang magkaibang uri ng mga halaga na nagsasabi ng halos pareho, may mga matibay na programmatic na dahilan para sa ganitong disenyo, at sa praktika, ang ganitong paraan ay nagbibigay-daan sa pandas na maghatid ng magandang kompromiso para sa karamihan ng mga kaso. Gayunpaman, parehong `None` at `NaN` ay may mga limitasyon na dapat mong tandaan kaugnay sa kung paano sila maaaring gamitin.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "lOHqUlZFgRr5" }, "source": [ "### `None`: non-float na nawawalang data\n", "Dahil ang `None` ay mula sa Python, hindi ito magagamit sa mga NumPy at pandas arrays na hindi may data type na `'object'`. Tandaan, ang mga NumPy arrays (at ang mga istruktura ng data sa pandas) ay maaari lamang maglaman ng isang uri ng data. Ito ang nagbibigay sa kanila ng napakalaking kapangyarihan para sa malakihang data at computational na gawain, ngunit nililimitahan din nito ang kanilang kakayahang umangkop. Ang ganitong mga arrays ay kailangang mag-upcast sa “pinakamababang karaniwang denominator,” ang uri ng data na magpapaloob sa lahat ng nasa array. Kapag ang `None` ay nasa array, nangangahulugan ito na nagtatrabaho ka gamit ang mga Python objects.\n", "\n", "Para makita ito sa aktwal, isaalang-alang ang sumusunod na halimbawa ng array (pansinin ang `dtype` nito):\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": [ "Ang realidad ng mga upcast na uri ng data ay may dalawang epekto. Una, ang mga operasyon ay isasagawa sa antas ng na-interpret na Python code sa halip na sa na-compile na NumPy code. Sa madaling salita, nangangahulugan ito na ang anumang operasyon na may kinalaman sa `Series` o `DataFrames` na may `None` ay magiging mas mabagal. Bagama't maaaring hindi mo mapansin ang epekto sa performance na ito, para sa malalaking dataset, maaari itong maging problema.\n", "\n", "Ang pangalawang epekto ay nagmumula sa una. Dahil ang `None` ay karaniwang nagdadala ng `Series` o `DataFrame`s pabalik sa mundo ng karaniwang Python, ang paggamit ng mga NumPy/pandas aggregations tulad ng `sum()` o `min()` sa mga array na naglalaman ng isang ``None`` na halaga ay kadalasang magdudulot ng error:\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": [ "**Pangunahing aral**: Ang pagdaragdag (at iba pang operasyon) sa pagitan ng mga integer at mga `None` na halaga ay hindi natutukoy, na maaaring maglimita sa kung ano ang magagawa mo sa mga dataset na naglalaman ng mga ito.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "pWvVHvETgRr9" }, "source": [ "### `NaN`: nawawalang float na mga halaga\n", "\n", "Sa kaibahan sa `None`, sinusuportahan ng NumPy (at samakatuwid ng pandas) ang `NaN` para sa mabilis, vectorized na mga operasyon at ufuncs. Ang masamang balita ay anumang arithmetic na ginawa sa `NaN` ay palaging nagreresulta sa `NaN`. Halimbawa:\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": [ "Ang magandang balita: ang mga aggregations na tumatakbo sa mga array na may `NaN` ay hindi nagdudulot ng mga error. Ang masamang balita: ang mga resulta ay hindi palaging kapaki-pakinabang:\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": [ "### Ehersisyo:\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": [ "Tandaan: `NaN` ay para lamang sa nawawalang floating-point na mga halaga; walang katumbas na `NaN` para sa mga integer, string, o Boolean.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "kj6EKdsAgRsA" }, "source": [ "### `NaN` at `None`: mga null na halaga sa pandas\n", "\n", "Kahit na ang `NaN` at `None` ay maaaring kumilos nang medyo magkaiba, ang pandas ay ginawa upang hawakan ang mga ito nang palitan. Upang makita kung ano ang ibig naming sabihin, isaalang-alang ang isang `Series` ng mga integer:\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": [ "### Ehersisyo:\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": [ "Sa proseso ng pag-upcast ng mga uri ng data upang maitatag ang pagkakapareho ng data sa `Series` at `DataFrame`s, ang pandas ay kusang nagpapalit ng mga nawawalang halaga sa pagitan ng `None` at `NaN`. Dahil sa tampok na disenyo na ito, makakatulong na isipin ang `None` at `NaN` bilang dalawang magkaibang uri ng \"null\" sa pandas. Sa katunayan, ang ilan sa mga pangunahing pamamaraan na gagamitin mo upang harapin ang mga nawawalang halaga sa pandas ay nagpapakita ng ideyang ito sa kanilang mga pangalan:\n", "\n", "- `isnull()`: Gumagawa ng Boolean mask na nagpapahiwatig ng mga nawawalang halaga\n", "- `notnull()`: Kabaligtaran ng `isnull()`\n", "- `dropna()`: Nagbabalik ng na-filter na bersyon ng data\n", "- `fillna()`: Nagbabalik ng kopya ng data na may mga nawawalang halaga na napunan o na-impute\n", "\n", "Ito ay mga mahalagang pamamaraan na dapat mong matutunan at maging komportable sa paggamit, kaya't talakayin natin ang bawat isa nang mas malalim.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "Yh5ifd9FgRsB" }, "source": [ "### Pagtukoy sa mga null na halaga\n", "\n", "Ngayon na nauunawaan na natin ang kahalagahan ng nawawalang mga halaga, kailangan nating tukuyin ang mga ito sa ating dataset bago ito ayusin. Ang parehong `isnull()` at `notnull()` ay pangunahing mga pamamaraan para sa pagtukoy ng null na data. Pareho itong nagbabalik ng Boolean masks sa iyong data.\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": [ "Tingnan nang mabuti ang output. Mayroon bang anumang ikinagulat mo? Bagama't ang `0` ay isang arithmetic null, ito ay isang ganap na maayos na integer at itinuturing ito ng pandas bilang ganoon. Ang `''` ay medyo mas banayad. Bagama't ginamit natin ito sa Seksyon 1 upang kumatawan sa isang walang laman na string na halaga, ito ay isang string object pa rin at hindi isang representasyon ng null ayon sa pandas.\n", "\n", "Ngayon, baligtarin natin ito at gamitin ang mga pamamaraang ito sa paraang mas malapit sa kung paano mo ito gagamitin sa aktwal na sitwasyon. Maaari mong gamitin ang Boolean masks nang direkta bilang isang ``Series`` o ``DataFrame`` index, na maaaring maging kapaki-pakinabang kapag sinusubukang magtrabaho sa mga hiwalay na nawawala (o naroroon) na mga halaga.\n", "\n", "Kung gusto natin ang kabuuang bilang ng nawawalang mga halaga, maaari lang tayong mag-sum sa mask na ginawa ng `isnull()` method.\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": [ "### Ehersisyo:\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": [ "**Pangunahing aral**: Parehong `isnull()` at `notnull()` na mga pamamaraan ay nagbibigay ng magkatulad na resulta kapag ginamit sa mga DataFrame: ipinapakita nila ang mga resulta at ang index ng mga resulta, na makakatulong nang malaki sa iyo habang inaayos mo ang iyong data.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "BvnoojWsgRr4" }, "source": [ "### Pagtugon sa nawawalang datos\n", "\n", "> **Layunin ng pag-aaral:** Sa pagtatapos ng bahaging ito, dapat mong malaman kung paano at kailan papalitan o aalisin ang mga null na halaga mula sa mga DataFrame.\n", "\n", "Ang mga modelo ng Machine Learning ay hindi kayang direktang magproseso ng nawawalang datos. Kaya, bago ipasa ang datos sa modelo, kailangan nating tugunan ang mga nawawalang halaga.\n", "\n", "Ang paraan ng paghawak sa nawawalang datos ay may kasamang mga maseselang tradeoff, na maaaring makaapekto sa iyong huling pagsusuri at mga resulta sa totoong mundo.\n", "\n", "May dalawang pangunahing paraan ng pagtugon sa nawawalang datos:\n", "\n", "1. Alisin ang row na naglalaman ng nawawalang halaga\n", "2. Palitan ang nawawalang halaga ng ibang halaga\n", "\n", "Tatalakayin natin ang parehong mga pamamaraan at ang kanilang mga kalamangan at kahinaan nang detalyado.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "3VaYC1TvgRsD" }, "source": [ "### Pag-aalis ng mga null na halaga\n", "\n", "Ang dami ng datos na ipinapasa natin sa ating modelo ay may direktang epekto sa pagganap nito. Ang pag-aalis ng mga null na halaga ay nangangahulugan na binabawasan natin ang bilang ng mga datapoint, at sa gayon ay binabawasan ang laki ng dataset. Kaya, mas mainam na alisin ang mga row na may null na halaga kapag ang dataset ay medyo malaki.\n", "\n", "Isa pang sitwasyon ay kung ang isang partikular na row o column ay may maraming nawawalang halaga. Sa ganitong kaso, maaaring alisin ang mga ito dahil hindi sila magdadagdag ng malaking halaga sa ating pagsusuri dahil karamihan sa datos para sa row/column na iyon ay nawawala.\n", "\n", "Bukod sa pagtukoy ng mga nawawalang halaga, nagbibigay ang pandas ng maginhawang paraan upang alisin ang mga null na halaga mula sa `Series` at `DataFrame`s. Upang makita ito sa aksyon, balikan natin ang `example3`. Ang function na `DataFrame.dropna()` ay tumutulong sa pag-aalis ng mga row na may null na halaga.\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": [ "Tandaan na dapat itong magmukhang katulad ng output mula sa `example3[example3.notnull()]`. Ang pagkakaiba dito ay, sa halip na i-index lamang ang mga nakamaskarang halaga, inalis ng `dropna` ang mga nawawalang halaga mula sa `Series` na `example3`.\n", "\n", "Dahil ang mga DataFrame ay may dalawang dimensyon, mas maraming opsyon ang mayroon para sa pag-aalis ng data.\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": [ "(Napansin mo ba na ang pandas ay nag-upcast ng dalawang column sa floats upang ma-accommodate ang `NaN`s?)\n", "\n", "Hindi mo maaaring tanggalin ang isang solong halaga mula sa isang `DataFrame`, kaya kailangan mong tanggalin ang buong mga row o column. Depende sa ginagawa mo, maaaring mas gusto mong gawin ang isa kaysa sa isa pa, kaya binibigyan ka ng pandas ng mga opsyon para sa pareho. Dahil sa data science, ang mga column ay karaniwang kumakatawan sa mga variable at ang mga row ay kumakatawan sa mga obserbasyon, mas malamang na tanggalin mo ang mga row ng data; ang default na setting para sa `dropna()` ay tanggalin ang lahat ng mga row na may anumang null na halaga:\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": [ "Kung kinakailangan, maaari mong tanggalin ang mga NA na halaga mula sa mga column. Gamitin ang `axis=1` para gawin ito:\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": [ "Pansinin na maaaring mawala ang maraming datos na gusto mong itago, lalo na sa mas maliliit na dataset. Paano kung gusto mo lang tanggalin ang mga row o column na may ilang null values o kahit lahat ng null values? Maaari mong itakda ang mga setting na ito sa `dropna` gamit ang mga parameter na `how` at `thresh`.\n", "\n", "Sa default, `how='any'` (kung gusto mong suriin ito para sa iyong sarili o makita ang iba pang mga parameter ng method, patakbuhin ang `example4.dropna?` sa isang code cell). Maaari mo ring tukuyin ang `how='all'` upang tanggalin lamang ang mga row o column na may lahat ng null values. Palawakin natin ang halimbawa ng `DataFrame` upang makita ito sa aksyon sa susunod na ehersisyo.\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": [ "> Mahahalagang puntos:\n", "1. Ang pag-aalis ng mga null na halaga ay magandang ideya lamang kung sapat ang laki ng dataset.\n", "2. Maaaring alisin ang buong mga row o column kung karamihan sa kanilang data ay nawawala.\n", "3. Ang `DataFrame.dropna(axis=)` na pamamaraan ay nakakatulong sa pag-aalis ng mga null na halaga. Ang argumento na `axis` ay nagpapahiwatig kung ang mga row o column ang aalisin.\n", "4. Maaaring gamitin ang argumento na `how`. Sa default, ito ay nakatakda sa `any`. Kaya, aalisin lamang nito ang mga row/column na mayroong anumang null na halaga. Maaari itong itakda sa `all` upang tukuyin na aalisin lamang natin ang mga row/column kung saan lahat ng halaga ay null.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "oXXSfQFHgRsF" }, "source": [ "### Ehersisyo:\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": [ "Ang parameter na `thresh` ay nagbibigay sa iyo ng mas detalyadong kontrol: itinatakda mo ang bilang ng *hindi-null* na mga halaga na kailangang mayroon ang isang row o column upang mapanatili ito:\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": [ "Dito, ang unang at huling hanay ay inalis, dahil naglalaman lamang ang mga ito ng dalawang hindi null na halaga.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "mCcxLGyUgRsG" }, "source": [ "### Pagpuno ng mga nawawalang halaga\n", "\n", "Minsan may kabuluhan na punan ang mga nawawalang halaga ng mga maaaring maging wasto. May ilang mga teknik para punan ang mga null na halaga. Ang una ay ang paggamit ng Domain Knowledge (kaalaman sa paksa kung saan nakabase ang dataset) upang tantyahin ang mga nawawalang halaga.\n", "\n", "Maaari mong gamitin ang `isnull` upang gawin ito nang direkta, ngunit maaaring matrabaho ito, lalo na kung marami kang halaga na kailangang punan. Dahil ito ay isang karaniwang gawain sa data science, nagbibigay ang pandas ng `fillna`, na nagbabalik ng kopya ng `Series` o `DataFrame` na may mga nawawalang halaga na pinalitan ng napili mo. Gumawa tayo ng isa pang halimbawa ng `Series` upang makita kung paano ito gumagana sa praktika.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "CE8S7louLezV" }, "source": [ "### Categorical Data (Hindi-numeriko)\n", "Una, tingnan natin ang hindi-numerikong data. Sa mga dataset, may mga column na naglalaman ng categorical data. Halimbawa: Kasarian, Tama o Mali, at iba pa.\n", "\n", "Sa karamihan ng mga ganitong kaso, pinapalitan natin ang nawawalang mga halaga gamit ang `mode` ng column. Halimbawa, mayroon tayong 100 data points kung saan 90 ang nagsabi ng Tama, 8 ang nagsabi ng Mali, at 2 ang hindi naglagay ng sagot. Sa ganitong sitwasyon, maaari nating punan ang 2 na nawawala ng Tama, batay sa kabuuang data ng column.\n", "\n", "Muli, maaari nating gamitin ang kaalaman sa domain dito. Tingnan natin ang isang halimbawa ng pagpuno gamit ang 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": [ "Ngayon, hanapin muna natin ang moda bago punan ang halagang `None` ng moda.\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": [ "Kaya, papalitan natin ang None ng 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": [ "Tulad ng nakikita natin, ang null na halaga ay napalitan. Hindi na kailangang sabihin, maaari tayong magsulat ng kahit ano sa lugar ng `'True'` at ito ay mapapalitan.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "heYe1I0dOmQ_" }, "source": [ "### Numeric Data\n", "Ngayon, tungkol sa numeric na datos. Dito, may dalawang karaniwang paraan ng pagpapalit ng nawawalang mga halaga:\n", "\n", "1. Palitan gamit ang Median ng row\n", "2. Palitan gamit ang Mean ng row\n", "\n", "Ginagamit natin ang Median kapag ang datos ay skewed at may mga outlier. Ito ay dahil ang median ay hindi gaanong naaapektuhan ng mga outlier.\n", "\n", "Kapag ang datos ay normalisado, maaari nating gamitin ang mean, dahil sa ganitong kaso, ang mean at median ay halos magkapareho.\n", "\n", "Una, kumuha tayo ng isang column na may normal na distribusyon at punan natin ang nawawalang halaga gamit ang mean ng column.\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": [ "Ang mean ng kolum ay\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": [ "Pagpuno gamit ang mean\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": [ "Makikita natin na ang nawawalang halaga ay pinalitan ng kanyang mean.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "jIvF13a1i00Z" }, "source": [ "Ngayon subukan natin ang isa pang dataframe, at sa pagkakataong ito ay papalitan natin ang mga None na halaga ng median ng kolum.\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": [ "Ang median ng ikalawang kolum ay\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": [ "Pagpuno gamit ang median\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": [ "Tulad ng nakikita natin, ang NaN na halaga ay napalitan ng median ng kolum.\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": [ "Maaari mong punan ang lahat ng mga null na entry gamit ang isang halaga, tulad ng `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": [ "> Mahahalagang puntos:\n", "1. Ang paglalagay ng nawawalang halaga ay dapat gawin kapag kaunti lamang ang datos o may estratehiya para punan ang nawawalang datos.\n", "2. Maaaring gamitin ang kaalaman sa larangan upang punan ang nawawalang halaga sa pamamagitan ng pagtatantiya.\n", "3. Para sa Categorical na datos, kadalasan, ang nawawalang halaga ay pinapalitan ng mode ng column.\n", "4. Para sa numeric na datos, ang nawawalang halaga ay karaniwang pinupunan gamit ang mean (para sa mga normalisadong dataset) o median ng mga column.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "FI9MmqFJgRsH" }, "source": [ "### Ehersisyo:\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": [ "Maaari mong **i-forward-fill** ang mga null na halaga, kung saan gagamitin ang huling wastong halaga upang punan ang null:\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": [ "Maaari mo ring **mag-back-fill** upang ipalaganap ang susunod na wastong halaga pabalik upang punan ang 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": [ "Tulad ng maaari mong hulaan, ganito rin ang paraan ng paggamit sa DataFrames, ngunit maaari ka ring magtakda ng `axis` kung saan pupunan ang mga null na halaga:\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": [ "Pansinin na kapag walang available na nakaraang halaga para sa forward-filling, nananatili ang null na halaga.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "eeAoOU0RgRsJ" }, "source": [ "### Ehersisyo:\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": [ "Maaari kang maging malikhain sa paggamit ng `fillna`. Halimbawa, tingnan natin muli ang `example4`, ngunit sa pagkakataong ito punan natin ang mga nawawalang halaga gamit ang average ng lahat ng mga halaga sa `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": [ "Pansinin na ang column 3 ay wala pa ring halaga: ang default na direksyon ay punan ang mga halaga nang pa-row.\n", "\n", "> **Punto:** Maraming paraan upang harapin ang mga nawawalang halaga sa iyong mga dataset. Ang partikular na estratehiya na gagamitin mo (pag-aalis, pagpapalit, o kung paano mo ito papalitan) ay dapat nakabatay sa mga detalye ng data na iyon. Mas magkakaroon ka ng mas mahusay na pag-unawa kung paano harapin ang mga nawawalang halaga habang mas madalas kang humawak at makipag-ugnayan sa mga dataset.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "bauDnESIl9FH" }, "source": [ "### Pag-encode ng Categorical Data\n", "\n", "Ang mga modelo ng machine learning ay gumagana lamang sa mga numero at anumang uri ng numerikong data. Hindi nito kayang tukuyin ang pagkakaiba ng Yes at No, ngunit kaya nitong tukuyin ang pagkakaiba ng 0 at 1. Kaya, pagkatapos punan ang mga nawawalang halaga, kailangan nating i-encode ang categorical data sa isang numerikong anyo upang maunawaan ng modelo.\n", "\n", "Ang pag-encode ay maaaring gawin sa dalawang paraan. Tatalakayin natin ang mga ito sa susunod.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "uDq9SxB7mu5i" }, "source": [ "**PAG-ENCODE NG LABEL**\n", "\n", "Ang pag-encode ng label ay ang proseso ng pag-convert ng bawat kategorya sa isang numero. Halimbawa, sabihin nating mayroon tayong dataset ng mga pasahero ng eroplano at may isang column na naglalaman ng kanilang klase mula sa mga sumusunod ['business class', 'economy class', 'first class']. Kapag ginawa ang pag-encode ng label dito, ito ay magiging [0,1,2]. Tingnan natin ang isang halimbawa gamit ang code. Dahil matututo tayo ng `scikit-learn` sa mga susunod na notebook, hindi natin ito gagamitin dito.\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": [ "Upang maisagawa ang label encoding sa unang kolum, kailangan muna nating ilarawan ang pagmamapa mula sa bawat klase patungo sa isang numero, bago palitan.\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": [ "Tulad ng nakikita natin, ang resulta ay tumutugma sa inaasahan natin. Kaya, kailan natin ginagamit ang label encoding? Ang label encoding ay ginagamit sa isa o pareho sa mga sumusunod na kaso:\n", "1. Kapag ang bilang ng mga kategorya ay marami\n", "2. Kapag ang mga kategorya ay may pagkakasunod-sunod.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "eQPAPVwsqWT7" }, "source": [ "**ONE HOT ENCODING**\n", "\n", "Ang isa pang uri ng encoding ay ang One Hot Encoding. Sa ganitong uri ng encoding, ang bawat kategorya ng column ay nagiging hiwalay na column, at bawat datapoint ay magkakaroon ng 0 o 1 batay sa kung naglalaman ito ng kategoryang iyon. Kaya, kung mayroong n iba't ibang kategorya, n na mga column ang idadagdag sa dataframe.\n", "\n", "Halimbawa, kunin natin ang parehong halimbawa ng klase ng eroplano. Ang mga kategorya ay: ['business class', 'economy class', 'first class']. Kaya, kung gagamit tayo ng one hot encoding, ang sumusunod na tatlong column ay idadagdag sa dataset: ['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": [ "Gawin natin ang one hot encoding sa unang kolum\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": [ "Ang bawat one hot encoded na column ay naglalaman ng 0 o 1, na tumutukoy kung ang kategoryang iyon ay umiiral para sa datapoint na iyon.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "bDnC4NQOu0qr" }, "source": [ "Kailan ginagamit ang one hot encoding? Ginagamit ang one hot encoding sa isa o pareho sa mga sumusunod na kaso:\n", "\n", "1. Kapag ang bilang ng mga kategorya at ang laki ng dataset ay mas maliit.\n", "2. Kapag ang mga kategorya ay walang partikular na pagkakasunod-sunod.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "XnUmci_4uvyu" }, "source": [ "> Mahahalagang Punto:\n", "1. Ang encoding ay ginagawa upang i-convert ang hindi numerikong datos sa numerikong datos.\n", "2. May dalawang uri ng encoding: Label encoding at One Hot encoding, na maaaring isagawa batay sa pangangailangan ng dataset.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "K8UXOJYRgRsJ" }, "source": [ "## Pag-aalis ng dobleng datos\n", "\n", "> **Layunin ng pag-aaral:** Sa pagtatapos ng bahaging ito, dapat kang maging komportable sa pagtukoy at pag-aalis ng mga dobleng halaga mula sa mga DataFrame.\n", "\n", "Bukod sa nawawalang datos, madalas kang makakakita ng dobleng datos sa mga aktwal na dataset. Sa kabutihang-palad, nagbibigay ang pandas ng madaling paraan para matukoy at maalis ang mga dobleng entry.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "qrEG-Wa0gRsJ" }, "source": [ "### Pagkilala sa mga duplicate: `duplicated`\n", "\n", "Madali mong matutukoy ang mga duplicate na halaga gamit ang `duplicated` na method sa pandas, na nagbabalik ng Boolean mask na nagpapakita kung ang isang entry sa `DataFrame` ay duplicate ng naunang isa. Gumawa tayo ng isa pang halimbawa ng `DataFrame` upang makita ito sa aksyon.\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": [ "### Pag-aalis ng mga duplicate: `drop_duplicates`\n", "Ang `drop_duplicates` ay nagbabalik lamang ng kopya ng data kung saan lahat ng mga halaga na `duplicated` ay `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": [ "Parehong `duplicated` at `drop_duplicates` ay default na isinasaalang-alang ang lahat ng mga column ngunit maaari mong tukuyin na suriin lamang nila ang isang subset ng mga column sa iyong `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": [ "> **Punto:** Ang pagtanggal ng dobleng datos ay mahalagang bahagi ng halos bawat proyekto sa agham ng datos. Ang dobleng datos ay maaaring magbago ng resulta ng iyong mga pagsusuri at magbigay sa iyo ng hindi tamang resulta!\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Mga Pag-check ng Kalidad ng Data sa Totoong Mundo\n", "\n", "> **Layunin ng pag-aaral:** Sa pagtatapos ng seksyong ito, dapat kang maging komportable sa pagtukoy at pagwawasto ng mga karaniwang isyu sa kalidad ng data sa totoong mundo, kabilang ang hindi pare-parehong mga halaga ng kategorya, abnormal na mga numerong halaga (mga outlier), at mga duplicate na entity na may mga pagkakaiba.\n", "\n", "Bagama't ang mga nawawalang halaga at eksaktong mga duplicate ay karaniwang mga isyu, ang mga dataset sa totoong mundo ay madalas na naglalaman ng mas banayad na mga problema:\n", "\n", "1. **Hindi pare-parehong mga halaga ng kategorya**: Ang parehong kategorya ay may iba't ibang baybay (hal., \"USA\", \"U.S.A\", \"United States\")\n", "2. **Abnormal na mga numerong halaga**: Mga matinding outlier na nagpapahiwatig ng mga error sa pagpasok ng data (hal., edad = 999)\n", "3. **Halos magkaparehong mga hilera**: Mga rekord na kumakatawan sa parehong entity na may bahagyang pagkakaiba\n", "\n", "Tuklasin natin ang mga teknik upang matukoy at maayos ang mga isyung ito.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Paglikha ng Halimbawang \"Maruming\" Dataset\n", "\n", "Una, gumawa tayo ng isang halimbawang dataset na naglalaman ng mga uri ng problema na karaniwang nararanasan natin sa totoong datos:\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. Pagtukoy sa Hindi Pare-parehong Halaga ng Kategorya\n", "\n", "Pansinin na ang kolum na `country` ay may iba't ibang representasyon para sa parehong mga bansa. Tukuyin natin ang mga hindi pagkakapareho na ito:\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": [ "#### Pag-standardize ng Mga Halagang Kategorya\n", "\n", "Maaari tayong gumawa ng mapping upang i-standardize ang mga halagang ito. Isang simpleng paraan ay ang pag-convert sa lowercase at paggawa ng mapping dictionary:\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": [ "**Alternatibo: Paggamit ng Fuzzy Matching**\n", "\n", "Para sa mas komplikadong mga kaso, maaari nating gamitin ang fuzzy string matching gamit ang `rapidfuzz` library upang awtomatikong matukoy ang magkatulad na mga string:\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. Pagtukoy sa Hindi Karaniwang Halaga ng Numero (Outliers)\n", "\n", "Sa pagtingin sa kolum na `age`, may ilang kahina-hinalang halaga tulad ng 199 at -5. Gamitin natin ang mga pamamaraang estadistikal upang matukoy ang mga outlier na ito.\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": [ "#### Paggamit ng IQR (Interquartile Range) na Paraan\n", "\n", "Ang IQR na paraan ay isang matibay na teknik sa estadistika para sa pagtukoy ng mga outlier na hindi gaanong sensitibo sa mga matitinding halaga:\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": [ "#### Paggamit ng Z-Score Method\n", "\n", "Ang Z-score method ay tumutukoy sa mga outlier batay sa mga standard deviation mula sa mean:\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": [ "#### Pag-aasikaso ng Mga Outlier\n", "\n", "Kapag natukoy, ang mga outlier ay maaaring asikasuhin sa iba't ibang paraan:\n", "1. **Tanggalin**: Alisin ang mga row na may outlier (kung ito ay mga pagkakamali)\n", "2. **Limitahan**: Palitan ng mga hangganang halaga\n", "3. **Palitan ng NaN**: Ituring bilang nawawalang datos at gumamit ng mga teknik sa imputation\n", "4. **Panatilihin**: Kung ito ay lehitimong matitinding halaga\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. Pagtukoy sa Halos Magkakaparehong Rows\n", "\n", "Pansinin na ang ating dataset ay may maraming entry para kay \"John Smith\" na may bahagyang magkakaibang mga halaga. Tukuyin natin ang mga posibleng duplicate batay sa pagkakahawig ng pangalan.\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": [ "#### Paghahanap ng Malapit na Duplicates gamit ang Fuzzy Matching\n", "\n", "Para sa mas sopistikadong pagtuklas ng duplicate, maaari nating gamitin ang fuzzy matching upang mahanap ang magkatulad na mga pangalan:\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": [ "#### Paghawak ng Mga Doble\n", "\n", "Kapag natukoy na, kailangan mong magdesisyon kung paano hahawakan ang mga doble:\n", "1. **Panatilihin ang unang paglitaw**: Gamitin ang `drop_duplicates(keep='first')`\n", "2. **Panatilihin ang huling paglitaw**: Gamitin ang `drop_duplicates(keep='last')`\n", "3. **Pagsama-samahin ang impormasyon**: Pagsamahin ang impormasyon mula sa mga dobleng hanay\n", "4. **Manwal na pagsusuri**: I-flag para sa pagsusuri ng tao\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": [ "### Buod: Kumpletong Pipeline para sa Paglilinis ng Data\n", "\n", "Pagsamahin natin ang lahat upang makabuo ng isang komprehensibong pipeline para sa paglilinis ng data:\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": [ "### 🎯 Hamon na Ehersisyo\n", "\n", "Ngayon ay ikaw naman! Narito ang isang bagong hanay ng datos na may maraming isyu sa kalidad. Kaya mo bang:\n", "\n", "1. Tukuyin ang lahat ng isyu sa hanay na ito\n", "2. Sumulat ng code upang linisin ang bawat isyu\n", "3. Idagdag ang nalinis na hanay sa dataset\n", "\n", "Narito ang problemadong datos:\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": [ "### Mahahalagang Punto\n", "\n", "1. **Hindi pare-parehong mga kategorya** ay karaniwang makikita sa totoong datos. Laging suriin ang mga natatanging halaga at gawing pare-pareho gamit ang mappings o fuzzy matching.\n", "\n", "2. **Mga outlier** ay maaaring malaki ang epekto sa iyong pagsusuri. Gumamit ng kaalaman sa larangan kasabay ng mga pamamaraang estadistikal (IQR, Z-score) upang matukoy ang mga ito.\n", "\n", "3. **Halos magkapareho na mga duplicate** ay mas mahirap tukuyin kaysa sa eksaktong mga duplicate. Isaalang-alang ang paggamit ng fuzzy matching at pag-normalize ng datos (pagbababa ng case, pagtanggal ng whitespace) upang mahanap ang mga ito.\n", "\n", "4. **Ang paglilinis ng datos ay paulit-ulit na proseso**. Maaaring kailanganin mong gumamit ng iba't ibang teknika at suriin ang mga resulta bago tapusin ang iyong nalinis na dataset.\n", "\n", "5. **I-dokumento ang iyong mga desisyon**. Itala ang mga hakbang sa paglilinis na iyong ginawa at ang dahilan nito, dahil mahalaga ito para sa reproducibility at transparency.\n", "\n", "> **Pinakamahusay na Praktis:** Laging magtago ng kopya ng iyong orihinal na \"maruming\" datos. Huwag kailanman i-overwrite ang iyong source data files - gumawa ng mga nalinis na bersyon na may malinaw na naming conventions tulad ng `data_cleaned.csv`.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n---\n\n**Paunawa**: \nAng dokumentong ito ay isinalin gamit ang AI translation service na [Co-op Translator](https://github.com/Azure/co-op-translator). Bagama't sinisikap naming maging tumpak, mangyaring tandaan na ang mga awtomatikong pagsasalin ay maaaring maglaman ng mga pagkakamali o hindi pagkakatugma. Ang orihinal na dokumento sa kanyang katutubong wika ang dapat ituring na opisyal na pinagmulan. Para sa mahalagang impormasyon, inirerekomenda ang propesyonal na pagsasalin ng tao. Hindi kami mananagot sa anumang hindi pagkakaunawaan o maling interpretasyon na dulot ng paggamit ng pagsasaling ito.\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": "6301339d1c9a301b00639c635dc9b731", "translation_date": "2025-10-03T20:45:52+00:00", "source_file": "2-Working-With-Data/08-data-preparation/notebook.ipynb", "language_code": "tl" } }, "nbformat": 4, "nbformat_minor": 0 }