Skip to content

Instantly share code, notes, and snippets.

@mlsmall
Created February 28, 2019 20:54
Show Gist options
  • Save mlsmall/51256b9f36d96a71b89f39e41a31dfa5 to your computer and use it in GitHub Desktop.
Save mlsmall/51256b9f36d96a71b89f39e41a31dfa5 to your computer and use it in GitHub Desktop.
12 Useful Panda Techniques.ipynb
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "import pandas as pd\nimport numpy as np\ndata = pd.read_csv(\"train.csv\", index_col=\"Loan_ID\")",
"execution_count": 10,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 1 - Boolean Indexing\n\nWhat do you do, if you want to filter values of a column based on conditions from another set of columns? For instance, we want a list of all females who are not graduate and got a loan. Boolean indexing can help here. You can use the following code:"
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "data.loc[(data[\"Gender\"]==\"Female\") & (data[\"Education\"]==\"Not Graduate\")\n & (data[\"Loan_Status\"]==\"Y\"), [\"Gender\",\"Education\",\"Loan_Status\"]]",
"execution_count": 11,
"outputs": [
{
"data": {
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Gender</th>\n <th>Education</th>\n <th>Loan_Status</th>\n </tr>\n <tr>\n <th>Loan_ID</th>\n <th></th>\n <th></th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>LP001155</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP001669</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP001692</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP001908</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP002300</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP002314</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP002407</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP002489</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP002502</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP002534</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP002582</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP002731</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP002757</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n <tr>\n <th>LP002917</th>\n <td>Female</td>\n <td>Not Graduate</td>\n <td>Y</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": " Gender Education Loan_Status\nLoan_ID \nLP001155 Female Not Graduate Y\nLP001669 Female Not Graduate Y\nLP001692 Female Not Graduate Y\nLP001908 Female Not Graduate Y\nLP002300 Female Not Graduate Y\nLP002314 Female Not Graduate Y\nLP002407 Female Not Graduate Y\nLP002489 Female Not Graduate Y\nLP002502 Female Not Graduate Y\nLP002534 Female Not Graduate Y\nLP002582 Female Not Graduate Y\nLP002731 Female Not Graduate Y\nLP002757 Female Not Graduate Y\nLP002917 Female Not Graduate Y"
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 2 - Apply Function\n\nIt is one of the commonly used functions for playing with data and creating new variables. Apply returns some value after passing each row/column of a data frame with some function. The function can be both default or user-defined. For instance, here it can be used to find the #missing values in each row and column."
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#Create a new function:\ndef num_missing(x):\n return sum(x.isnull())",
"execution_count": 12,
"outputs": []
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#Applying per column:\nprint(\"Missing values per column:\")\nprint(data.apply(num_missing, axis=0)) #axis=0 defines that function is to be applied on each column ",
"execution_count": 13,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": "Missing values per column:\nGender 13\nMarried 3\nDependents 15\nEducation 0\nSelf_Employed 32\nApplicantIncome 0\nCoapplicantIncome 0\nLoanAmount 22\nLoan_Amount_Term 14\nCredit_History 50\nProperty_Area 0\nLoan_Status 0\ndtype: int64\n"
}
]
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#Applying per row:\nprint(\"Missing values per row:\")\nprint(data.apply(num_missing, axis=1).head()) #axis=1 defines that function is to be applied on each row",
"execution_count": 14,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": "Missing values per row:\nLoan_ID\nLP001002 1\nLP001003 0\nLP001005 0\nLP001006 0\nLP001008 0\ndtype: int64\n"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 3 - Imputing missing files\n\n‘fillna()’ does it in one go. It is used for updating missing values with the overall mean/mode/median of the column. Let’s impute the ‘Gender’, ‘Married’ and ‘Self_Employed’ columns with their respective modes."
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#First we import a function to determine the mode\nfrom scipy.stats import mode",
"execution_count": 16,
"outputs": []
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "mode(data['Loan_Status'])",
"execution_count": 25,
"outputs": [
{
"data": {
"text/plain": "ModeResult(mode=array(['Y'], dtype=object), count=array([422]))"
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "mode(data['Loan_Status']).mode[0]",
"execution_count": 18,
"outputs": [
{
"data": {
"text/plain": "'Y'"
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#Impute the values:\n# data['Gender'].fillna(mode(data['Gender']).mode[0], inplace=True)\n# data['Married'].fillna(mode(data['Married']).mode[0], inplace=True)\n# data['Self_Employed'].fillna(mode(data['Self_Employed']).mode[0], inplace=True)",
"execution_count": 22,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 4 - Pivot Table\n\nPandas can be used to create MS Excel style pivot tables. For instance, in this case, a key column is “LoanAmount” which has missing values. We can impute it using mean amount of each ‘Gender’, ‘Married’ and ‘Self_Employed’ group. The mean ‘LoanAmount’ of each group can be determined as:"
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#Determine pivot table\nimpute_grps = data.pivot_table(values=[\"LoanAmount\"], index=[\"Gender\",\"Married\",\"Self_Employed\"], aggfunc=np.mean)\nprint(impute_grps)",
"execution_count": 26,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": " LoanAmount\nGender Married Self_Employed \nFemale No No 110.596774\n Yes 125.800000\n Yes No 135.480000\n Yes 282.250000\nMale No No 128.137255\n Yes 173.625000\n Yes No 151.709220\n Yes 169.355556\n"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 5 – Multi-Indexing\n\nIf you notice the output of step #3, it has a strange property. Each index is made up of a combination of 3 values. This is called Multi-Indexing. It helps in performing operations really fast.\n\nContinuing the example from #3, we have the values for each group but they have not been imputed.\nThis can be done using the various techniques learned till now."
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "# #iterate only through rows with missing LoanAmount\n# for i,row in data.loc[data['LoanAmount'].isnull(),:].iterrows():\n# ind = tuple([row['Gender'],row['Married'],row['Self_Employed']])\n# data.loc[i,'LoanAmount'] = impute_grps.loc[ind].values[0]",
"execution_count": 28,
"outputs": []
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 6 Crosstab\n\nThis function is used to get an initial “feel” (view) of the data. Here, we can validate some basic hypothesis. For instance, in this case, “Credit_History” is expected to affect the loan status significantly. This can be tested using cross-tabulation as shown below:"
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "pd.crosstab(data[\"Credit_History\"],data[\"Loan_Status\"],margins=True)",
"execution_count": 29,
"outputs": [
{
"data": {
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th>Loan_Status</th>\n <th>N</th>\n <th>Y</th>\n <th>All</th>\n </tr>\n <tr>\n <th>Credit_History</th>\n <th></th>\n <th></th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0.0</th>\n <td>82</td>\n <td>7</td>\n <td>89</td>\n </tr>\n <tr>\n <th>1.0</th>\n <td>97</td>\n <td>378</td>\n <td>475</td>\n </tr>\n <tr>\n <th>All</th>\n <td>179</td>\n <td>385</td>\n <td>564</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": "Loan_Status N Y All\nCredit_History \n0.0 82 7 89\n1.0 97 378 475\nAll 179 385 564"
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "These are absolute numbers. But, percentages can be more intuitive in making some quick insights. We can do this using the apply function:"
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "def percConvert(ser):\n return ser/float(ser[-1])\n\npd.crosstab(data[\"Credit_History\"],data[\"Loan_Status\"],margins=True).apply(percConvert, axis=1)",
"execution_count": 34,
"outputs": [
{
"data": {
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th>Loan_Status</th>\n <th>N</th>\n <th>Y</th>\n <th>All</th>\n </tr>\n <tr>\n <th>Credit_History</th>\n <th></th>\n <th></th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0.0</th>\n <td>0.921348</td>\n <td>0.078652</td>\n <td>1.0</td>\n </tr>\n <tr>\n <th>1.0</th>\n <td>0.204211</td>\n <td>0.795789</td>\n <td>1.0</td>\n </tr>\n <tr>\n <th>All</th>\n <td>0.317376</td>\n <td>0.682624</td>\n <td>1.0</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": "Loan_Status N Y All\nCredit_History \n0.0 0.921348 0.078652 1.0\n1.0 0.204211 0.795789 1.0\nAll 0.317376 0.682624 1.0"
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 7 – Merge DataFrames\n\nMerging dataframes become essential when we have information coming from different sources to be collated. Consider a hypothetical case where the average property rates (INR per sq meters) is available for different property types. Let’s define a dataframe as:"
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "prop_rates = pd.DataFrame([1000, 5000, 12000], index=['Rural','Semiurban','Urban'],columns=['rates'])\nprop_rates",
"execution_count": 35,
"outputs": [
{
"data": {
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>rates</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>Rural</th>\n <td>1000</td>\n </tr>\n <tr>\n <th>Semiurban</th>\n <td>5000</td>\n </tr>\n <tr>\n <th>Urban</th>\n <td>12000</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": " rates\nRural 1000\nSemiurban 5000\nUrban 12000"
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Now we can merge this information with the original dataframe as:"
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "data_merged = data.merge(right=prop_rates, how='inner',left_on='Property_Area',right_index=True, sort=False)\ndata_merged.pivot_table(values='Credit_History',index=['Property_Area','rates'], aggfunc=len)",
"execution_count": 36,
"outputs": [
{
"data": {
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th></th>\n <th>Credit_History</th>\n </tr>\n <tr>\n <th>Property_Area</th>\n <th>rates</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>Rural</th>\n <th>1000</th>\n <td>179.0</td>\n </tr>\n <tr>\n <th>Semiurban</th>\n <th>5000</th>\n <td>233.0</td>\n </tr>\n <tr>\n <th>Urban</th>\n <th>12000</th>\n <td>202.0</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": " Credit_History\nProperty_Area rates \nRural 1000 179.0\nSemiurban 5000 233.0\nUrban 12000 202.0"
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "The pivot table validates successful merge operation. Note that the ‘values’ argument is irrelevant here because we are simply counting the values."
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 8 – Sorting DataFrames\n\nPandas allow easy sorting based on multiple columns. This can be done as:"
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "data_sorted = data.sort_values(['ApplicantIncome','CoapplicantIncome'], ascending=False)\ndata_sorted[['ApplicantIncome','CoapplicantIncome']].head(10)",
"execution_count": 37,
"outputs": [
{
"data": {
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>ApplicantIncome</th>\n <th>CoapplicantIncome</th>\n </tr>\n <tr>\n <th>Loan_ID</th>\n <th></th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>LP002317</th>\n <td>81000</td>\n <td>0.0</td>\n </tr>\n <tr>\n <th>LP002101</th>\n <td>63337</td>\n <td>0.0</td>\n </tr>\n <tr>\n <th>LP001585</th>\n <td>51763</td>\n <td>0.0</td>\n </tr>\n <tr>\n <th>LP001536</th>\n <td>39999</td>\n <td>0.0</td>\n </tr>\n <tr>\n <th>LP001640</th>\n <td>39147</td>\n <td>4750.0</td>\n </tr>\n <tr>\n <th>LP002422</th>\n <td>37719</td>\n <td>0.0</td>\n </tr>\n <tr>\n <th>LP001637</th>\n <td>33846</td>\n <td>0.0</td>\n </tr>\n <tr>\n <th>LP001448</th>\n <td>23803</td>\n <td>0.0</td>\n </tr>\n <tr>\n <th>LP002624</th>\n <td>20833</td>\n <td>6667.0</td>\n </tr>\n <tr>\n <th>LP001922</th>\n <td>20667</td>\n <td>0.0</td>\n </tr>\n </tbody>\n</table>\n</div>",
"text/plain": " ApplicantIncome CoapplicantIncome\nLoan_ID \nLP002317 81000 0.0\nLP002101 63337 0.0\nLP001585 51763 0.0\nLP001536 39999 0.0\nLP001640 39147 4750.0\nLP002422 37719 0.0\nLP001637 33846 0.0\nLP001448 23803 0.0\nLP002624 20833 6667.0\nLP001922 20667 0.0"
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 9 – Plotting (Boxplot & Histogram)\n\nMany of you might be unaware that boxplots and histograms can be directly plotted in Pandas and calling matplotlib separately is not necessary. It’s just a 1-line command. For instance, if we want to compare the distribution of ApplicantIncome by Loan_Status:"
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "import matplotlib.pyplot as plt\n%matplotlib inline\ndata.boxplot(column=\"ApplicantIncome\",by=\"Loan_Status\", figsize = (8,6))",
"execution_count": 40,
"outputs": [
{
"data": {
"text/plain": "<matplotlib.axes._subplots.AxesSubplot at 0x1bc5156f668>"
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAgUAAAGUCAYAAAClTlF2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4xLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvDW2N/gAAIABJREFUeJzt3XucXlV96P/PNxlCQrgmSIQkXKqpHZxWivkB2pzTjGm59QKtN0ZagoyN9WCkra1ix3PwNhVpq0X0UNNOBKwOUE8FWlDEmNETKxTwGhj9EbkkMcgtgCREYCbf88deE54Mk8wkhNnDzOf9ej2v2Xvttff+7nlmz/N91lp778hMJEmSJtUdgCRJGhtMCiRJEmBSIEmSCpMCSZIEmBRIkqTCpECSJAEmBdLzFhGXRcRH6o6jbjv7PUTE2RGxarRjkrRrTAo0bkTEvRGxJSI2RcSjEXF9RMytO65GEZER8fK643gxi4ieiHhb3XEARMQrI+Kr5e/tsYi4PSJOLcsWRsT6Xdyefx+qlUmBxpvfy8x9gUOBB4BLao7nBRMVz+F6/TtwEzALOAR4F/DzWiOSngf/oWhcysxfAF8Ejh4oi4gDIuKKiHgoIu6LiPcPfKhGxKUR8cWGuh+LiBXlg3dhRKyPiL+OiIdLi8SZO9p3RPxJRKyJiI0RcV1EHFbKv1mqfL+0Zrx5iHUnR8Tfl/3cExHvLN8em8rynojojIhvAU8CvxQRh5X9bCz7/ZOG7W3XpD/422s5lvdFxJ3l2+5nI2Jqw/LfjYjvlW/B/xkRv9aw7Ncj4jsR8UREXAVsW2/Hv5q4JCIej4gfRcSiUvjGiLh9UMV3R8Q1w2xvqB38fkTcUeLtiYjmhmXnR8RPSrx3RsQfNCw7OyJWRcTfld/DPRFxyjD7Ohg4CvinzHy6vL6VmasiYjrwZeCw8l5vKu/TcRHx7RLf/RHxqYiYUrb3nL+PGKLbpbE1ISJOLcfyRET8NCL+cld/Z1IjkwKNSxGxD/Bm4OaG4kuAA4BfAn4TOAt4a1n2buDXyj/h/wa0A4vz2fuAvxQ4GJgNLAaWRcQrhtjv64CPAm+iaq24D7gSIDP/e6n2qszcNzOvGiL0PwFOAY4BjgVOH6LOHwNLgP3K9ruB9cBhwBuAvxn4wB2hM4GTgJcBvwy8vxzLscBy4O3ATOAzwHURsXf5ILsG+BwwA/hX4PXD7Od44G6q3+MFwL9FxAzgOuCoxg9w4I/KtkcsIn6Z6nfxZ8BLgBuAfx/40AV+Avw3qr+BDwL/EhGHDorvxyW+i4CuiIid7PIRYE3ZzukRMWtgQWZupnofN5T3et/M3AD0A39e9vEaYBHwP8o6I/n7GKwLeHtm7ge0AF8fwTrSDpkUaLy5JiIeo2rC/W3gb6H6Bk6VJLwvM5/IzHuBv6f6gCUzn6T6IPo48C/A0swc3B/8PzPzqcz8BnA91Qf/YGcCyzPzO5n5FPA+4DURceQI438TcHFmrs/MR4ELh6hzWWbekZl9VMnKAuC9mfmLzPwe8M8DxzVCn8rMdZm5EegE2kr5nwCfycxbMrM/My8HngJOKK+9gH/IzGcy84vArcPs58GG+ldRfQD/Tvk9XUX1+yciXgkcCfzHLhwDVO/v9Zl5U2Y+A/wdMA14LUBm/mtmbsjMrWX/dwHHNax/X2b+U2b2A5dTJXWz2IGSMLYC91L9Ld0fEd+MiHk7Wef2zLw5M/vK3+BnqBLU3fUMcHRE7J+Zj2bmd57HtiSTAo07p2fmgcDewDuBb0TEwLf8KVTfrAfcR/XNH4DM/C+qb7IBXD1ou4+Wb3+N6x42xP4Pa9xHZm6i+kY5e4i6QzkMWNcwv26IOo1lhwEbM/OJQbGNdH+Dt9d4XEcA7y5N3Y+VZGtuWX4Y8NOGlpSBdXdmqPoD+7oceEv5Zv7HwNUlWdgVg3/3W6mObTZARJzV0BXyGNU364Mb1v9Zw7pPlsl9d7bDkry9MzNfRvX72gxcsaP6EfHLEfEfEfGziPg58DeDYthVrwdOBe6LiG9ExGuex7YkkwKNT+Wb7b9RNdcuAB6m+lZ1REO1w4GfDsxExLlUycQG4D2DNnlQ6SduXHfDELve0LiPss7Mxv0M435gTsP8UFdPNH6wbgBmRMR+g2Ib2N9mYJ+GZS8dYnuN+2g8rnVAZ2Ye2PDaJzO7S5yzBzWvH76jgyqGqr8BIDNvBp6mat5/C7vYdVAM/t0H1bH9NCKOAP6JKlGcWRLH1VQJ4B6RmeuAT1MlG7D9+zTgUuBHwLzM3B/462Fi2O79Kwlu4z5vzczTqAY5XsNzk1lpl5gUaFyKymnAQUBvaRK+GuiMiP3Kh8RfUHUVDPRHf4SqCfuPgfdExDGDNvvBiJhSxhz8LlU/+mBfAN4aEcdExN5U3wRvKU3FUF0R8Us7Cf1q4LyImB0RBwLv3dlxlg+i/wQ+GhFToxoI2A58vlT5HnBqRMwoHyh/NsRmzo2IOaV//6+pmvKh+hD904g4vvw+p0fE75QE5NtAH/CuiGiKiD9k+6b4oRxS6u8VEW8Emqn6/QdcAXwK6MvM4e5p0FSOd+C1F9Xv7nciYlGZfzdVd8d/AtOpPqQfAoiIt/Lsh/duiYiDIuKDEfHyiJhUBh6ew7PjWB4AZkbEAQ2r7UfVtbUpIn4FeMegzQ7++/g+8Mry9zQV+EDD/qdExJkRcUDpLvk5VRIs7TaTAo03/x4Rm6j+QXZSDRa8oyxbSvXN625gFdUH+PKoRvb/C/CxzPx+Zt5F9eH4ufLBDlXT8qNU30Y/D/xpZv5o8M4zcwXwP4H/Q/Vt+mXAGQ1VPgBcXpqwhxqT8E/AV4EfAN+l+tDsY+f/7Nuo+uA3AF8CLsjMm8qyz1F9sNxbtjvU4LUvlGV3l9dHyrHcRjWu4FPl2NcAZ5dlTwN/WOYfperP/7edxAhwCzCPqtWmE3hDZj7SsPxzVB/UI2kluBTY0vD6bGb+mCqpu6Ts4/eoLlF9OjPvpOr3/zbVB++vAt8awX525mmq3/vXqP7eVlMlIWcDlL+PbuDu8n4fBvwlVUvIE1Tv9eD34wM0/H1k5v8PfKjs4y6qv9tGfwzcW7oi/rQcv7TbYvsuPkmDRcRC4F8yc85wdV+AfZ8C/GNmHjFs5d3b/r3A2zLzay/E9ncxlmlUgxGPLYmZpFFmS4E0hkTEtKiuPW+KiNlUl+59qe64Rsk7gFtNCKT6NNUdgKTtBNU19FdRNYtfD/yvWiMaBaXFIhj6vgy1Kt1RQzklM//vqAYjvcDsPpAkSYDdB5IkqTApkCRJgEmBJEkqTAokSRJgUiBJkgqTAmmci+px0Ksa5jdFxM5utSxpgjIpkMaYiOiJiEcbbrG8R2Xmvpl59wux7QERkRHx8ob5hREx+FHUksYYkwJpDImII6meFJjA79cajKQJx6RAGlvOonrK3mXA4oHCiLgsIv4xIm6KiCci4hvlSY8DyzMi3hURd0fEwxHxtxEx5Pnd+C2+3Fb57yPivoh4PCJWlWcQEBH/GhE/K+XfjIhXDorn0xFxfYnnloh4WVn2zVLt+6Wr4s1DxNATER+OiG+V9b9anjI4sHxBRPxneTDQuog4u5QfEBFXRMRDJeb3Dxxn6Sb5VkR8oqx3d0S8tpSvi4gHI6Lxd7p3RPxdRKyNiAfK73farr5h0nhiUiCNLWdRPYXx88BJETGrYdmZwIeBg6keifz5Qev+ATAfOBY4jeoxvsP5O+DVwGuBGcB7gK1l2Zepnmp4CPCdIfbXRnVL5oOonqDYCZCZ/70sf1XpqhjqyYxQPS3wrWX7U6ieIEhEHF72fQnwEuCYcryUsgOoHi/8m1S/r7c2bPN4qidMzqR6+uOVwP8HvJzqCYKfioh9S92PAb9ctv9yYDYT4JbS0k5lpi9fvsbAC1gAPAMcXOZ/BPx5mb4MuLKh7r5Uj1OeW+YTOLlh+f8AVpTps4FVDcuS6kNwEtXzFV41gtgOLOsd0BDPPzcsPxX40eB9NMwvBNY3zPcA7x8U71fK9PuALw0Rw2SqRxMf3VD2dqCn4Tjvalj2qyWOWQ1lj1AlAUH1GO2XNSx7DXBP3X8HvnzV+bKlQBo7FgNfzcyHy/wXaOhCANYNTGTmJmAjcNhQy4H7Bi0bysHAVOAngxdExOSIuDAifhIRPwfubVhnwM8app+kSlR2xY7WnztUTGXfU6iObcB9VN/wBzzQML0FIDMHl+1L1QKxD3B76Wp4DPhKKZcmLJ+SKI0BpS/7TcDkiBj4sNwbODAiXlXm5zbU35equX9Dw2bmAneU6cMHLRvKw8AvgJcB3x+07C1UXRC/RZUQHAA8SvUN+4W2DjhuiPKHqVpSjgDuLGWHAz/djX08TJUgvDIzd2d9aVyypUAaG06n6g44mqp5+xigGfi/VP3mAKeWAXhTqMYW3JKZja0DfxURB0XEXOA8qscv71BmbgWWAx+PiMNK68BryqWQ+1E11T9C9Y36b3bxeB6g6vffHZ8Hfisi3hQRTRExMyKOycx+4GqgMyL2KwMt/wL4l13dQTn2fwI+ERGHAETE7Ig4aTdjlsYFkwJpbFgMfDYz12bmzwZewKeoBhg2UXUnXEDVbfDqUt7oWuB2qkF51wNdI9jvXwI/BG4t2/0Y1f+FK6ia5n9K9a385l08ng8Al5em+TftyoqZuZZqjMK7S0zfAwZaS5ZSjQW4G1hF9TtZvouxDXgv1QDJm0sXydeAV+zmtqRxITKz7hgkDSMiLqMaqPf+HSxPYF5mrhnVwCSNK7YUSJIkwKRAkiQVdh9IkiTAlgJJklS8aO9TcPDBB+eRRx5ZdxjaAzZv3sz06dPrDkNSA8/L8eP2229/ODNHdGOuF21ScOSRR3LbbbfVHYb2gJ6eHhYuXFh3GJIaeF6OHxFx3/C1KnYfSJIkwKRAkiQVJgWSJAkwKZAkSYVJgSRJAkwKJElSYVIgSZIAkwJJklSYFEiSJMCkQJIkFSYFqk13dzctLS0sWrSIlpYWuru76w5Jkia0F+2zD/Ti1t3dTUdHB11dXfT39zN58mTa29sBaGtrqzk6SZqYbClQLTo7O+nq6qK1tZWmpiZaW1vp6uqis7Oz7tAkacIaUVIQEX8eEXdExOqI6I6IqRFxVETcEhF3RcRVETGl1N27zK8py49s2M77SvmPI+KkhvKTS9maiDh/Tx+kxp7e3l4WLFiwXdmCBQvo7e2tKSJJ0rBJQUTMBt4FzM/MFmAycAbwMeATmTkPeBRoL6u0A49m5suBT5R6RMTRZb1XAicD/zsiJkfEZODTwCnA0UBbqatxrLm5mVWrVm1XtmrVKpqbm2uKSJI00u6DJmBaRDQB+wD3A68DvliWXw6cXqZPK/OU5YsiIkr5lZn5VGbeA6wBjiuvNZl5d2Y+DVxZ6moc6+jooL29nZUrV9LX18fKlStpb2+no6Oj7tAkacIadqBhZv40Iv4OWAtsAb4K3A48lpl9pdp6YHaZng2sK+v2RcTjwMxSfnPDphvXWTeo/PihYomIJcASgFmzZtHT0zNc+BqjDj30UM4880zOOecc1q5dy+GHH84f/dEfceihh/q+SmPApk2bPBcnoGGTgog4iOqb+1HAY8C/UjX1D5YDq+xg2Y7Kh2qtyCHKyMxlwDKA+fPn58KFC3cWusa4hQsX8uEPf5ienh58L6WxxfNyYhpJ98FvAfdk5kOZ+Qzwb8BrgQNLdwLAHGBDmV4PzAUoyw8ANjaWD1pnR+WSJGkUjSQpWAucEBH7lLEBi4A7gZXAG0qdxcC1Zfq6Mk9Z/vXMzFJ+Rrk64ShgHvBfwK3AvHI1wxSqwYjXPf9DkyRJu2IkYwpuiYgvAt8B+oDvUjXhXw9cGREfKWVdZZUu4HMRsYaqheCMsp07IuJqqoSiDzg3M/sBIuKdwI1UVzYsz8w79twhSpKkkRjRHQ0z8wLggkHFd1NdOTC47i+AN+5gO53Ac+5Ok5k3ADeMJBZJkvTC8I6GkiQJMCmQJEmFSYEkSQJMCiRJUmFSIEmSAJMCSZJUmBRIkiTApECSJBUmBZIkCTApkCRJhUmBJEkCTAokSVJhUiBJkgCTAkmSVJgUSJIkwKRAkiQVJgWSJAkwKZAkSYVJgSRJAkwKJElSYVIgSZIAkwJJklSYFEiSJMCkQJIkFSYFkiQJMCmQJEmFSYEkSQJMCiRJUjFsUhARr4iI7zW8fh4RfxYRMyLipoi4q/w8qNSPiPhkRKyJiB9ExLEN21pc6t8VEYsbyl8dET8s63wyIuKFOVxJkrQjwyYFmfnjzDwmM48BXg08CXwJOB9YkZnzgBVlHuAUYF55LQEuBYiIGcAFwPHAccAFA4lEqbOkYb2T98jRSZKkEdvV7oNFwE8y8z7gNODyUn45cHqZPg24Iis3AwdGxKHAScBNmbkxMx8FbgJOLsv2z8xvZ2YCVzRsS5IkjZKmXax/BtBdpmdl5v0AmXl/RBxSymcD6xrWWV/Kdla+fojy54iIJVQtCsyaNYuenp5dDF9j0aZNm3wvpTHG83JiGnFSEBFTgN8H3jdc1SHKcjfKn1uYuQxYBjB//vxcuHDhMKHoxaCnpwffS2ls8bycmHal++AU4DuZ+UCZf6A0/VN+PljK1wNzG9abA2wYpnzOEOWSJGkU7UpS0MazXQcA1wEDVxAsBq5tKD+rXIVwAvB46Wa4ETgxIg4qAwxPBG4sy56IiBPKVQdnNWxLkiSNkhF1H0TEPsBvA29vKL4QuDoi2oG1wBtL+Q3AqcAaqisV3gqQmRsj4sPAraXehzJzY5l+B3AZMA34cnlJkqRRNKKkIDOfBGYOKnuE6mqEwXUTOHcH21kOLB+i/DagZSSxSJKkF4Z3NJQkSYBJgSRJKkwKJEkSYFIgSZIKkwJJkgSYFEiSpMKkQJIkASYFkiSpMCmQJEmASYEkSSpMCiRJEmBSIEmSCpMCSZIEmBRIkqTCpECSJAEmBZKkBt3d3bS0tLBo0SJaWlro7u6uOySNoqa6A5AkjQ3d3d10dHTQ1dVFf38/kydPpr29HYC2traao9NosKVAkgRAZ2cnXV1dtLa20tTURGtrK11dXXR2dtYdmkaJSYEkCYDe3l4WLFiwXdmCBQvo7e2tKSKNNpMCSRIAzc3NrFq1aruyVatW0dzcXFNEGm0mBZIkADo6Omhvb2flypX09fWxcuVK2tvb6ejoqDs0jRIHGkqSgGcHEy5dupTe3l6am5vp7Ox0kOEEYlIgSdqmra2NtrY2enp6WLhwYd3haJTZfSBJkgCTAkmSVJgUSJIkwKRAkiQVI0oKIuLAiPhiRPwoInoj4jURMSMiboqIu8rPg0rdiIhPRsSaiPhBRBzbsJ3Fpf5dEbG4ofzVEfHDss4nIyL2/KFKkqSdGWlLwcXAVzLzV4BXAb3A+cCKzJwHrCjzAKcA88prCXApQETMAC4AjgeOAy4YSCRKnSUN6538/A5LkiTtqmGTgojYH/jvQBdAZj6dmY8BpwGXl2qXA6eX6dOAK7JyM3BgRBwKnATclJkbM/NR4Cbg5LJs/8z8dmYmcEXDtiRJ0igZyX0Kfgl4CPhsRLwKuB04D5iVmfcDZOb9EXFIqT8bWNew/vpStrPy9UOUP0dELKFqUWDWrFn09PSMIHyNdZs2bfK9lMYYz8uJaSRJQRNwLLA0M2+JiIt5tqtgKEONB8jdKH9uYeYyYBnA/Pnz0xtrjA/eJEUaezwvJ6aRjClYD6zPzFvK/BepkoQHStM/5eeDDfXnNqw/B9gwTPmcIcolSdIoGjYpyMyfAesi4hWlaBFwJ3AdMHAFwWLg2jJ9HXBWuQrhBODx0s1wI3BiRBxUBhieCNxYlj0RESeUqw7OatiWJEkaJSN99sFS4PMRMQW4G3grVUJxdUS0A2uBN5a6NwCnAmuAJ0tdMnNjRHwYuLXU+1BmbizT7wAuA6YBXy4vSZI0ikaUFGTm94D5QyxaNETdBM7dwXaWA8uHKL8NaBlJLJIk6YXhHQ0lSRJgUiBJkgqTAkmSBJgUSJKkwqRAkiQBJgWSJKkwKZAkSYBJgSRJKkwKJEkSYFIgSZIKkwJJkgSYFEiSpMKkQJIkASYFkiSpMCmQJEmASYEkSSpMCiRJEmBSIEmSCpMCSZIEmBRIkqTCpECSJAEmBZKkBt3d3bS0tLBo0SJaWlro7u6uOySNoqa6A5AkjQ3d3d10dHTQ1dVFf38/kydPpr29HYC2traao9NosKVAkgRAZ2cnXV1dtLa20tTURGtrK11dXXR2dtYdmkaJSYEkCYDe3l4WLFiwXdmCBQvo7e2tKSKNNpMCSRIAzc3NrFq1aruyVatW0dzcXFNEGm0mBZIkADo6Omhvb2flypX09fWxcuVK2tvb6ejoqDs0jZIRDTSMiHuBJ4B+oC8z50fEDOAq4EjgXuBNmfloRARwMXAq8CRwdmZ+p2xnMfD+stmPZOblpfzVwGXANOAG4LzMzD1wfJKkERoYTLh06VJ6e3tpbm6ms7PTQYYTyK60FLRm5jGZOb/Mnw+syMx5wIoyD3AKMK+8lgCXApQk4gLgeOA44IKIOKisc2mpO7Deybt9RJKk3dbW1sbq1atZsWIFq1evNiGYYJ5P98FpwOVl+nLg9IbyK7JyM3BgRBwKnATclJkbM/NR4Cbg5LJs/8z8dmkduKJhW5IkaZSMNClI4KsRcXtELCllszLzfoDy85BSPhtY17Du+lK2s/L1Q5RLkqRRNNKbF/1GZm6IiEOAmyLiRzupG0OU5W6UP3fDVUKyBGDWrFn09PTsNGi9OGzatMn3UhpjPC8nphElBZm5ofx8MCK+RDUm4IGIODQz7y9dAA+W6uuBuQ2rzwE2lPKFg8p7SvmcIeoPFccyYBnA/Pnzc+HChUNV04tMT08PvpfS2OJ5OTEN230QEdMjYr+BaeBEYDVwHbC4VFsMXFumrwPOisoJwOOle+FG4MSIOKgMMDwRuLEseyIiTihXLpzVsC1JkjRKRtJSMAv4UvV5TRPwhcz8SkTcClwdEe3AWuCNpf4NVJcjrqG6JPGtAJm5MSI+DNxa6n0oMzeW6Xfw7CWJXy4vSZI0ioZNCjLzbuBVQ5Q/AiwaojyBc3ewreXA8iHKbwNaRhCvJEl6gXhHQ0mSBJgUSJKkwqRAkiQBJgWSJKkwKZAkSYBJgSRJKkwKJEkSYFIgSZIKkwJJkgSYFEiSpMKkQJIkASYFkiSpMCmQJEmASYEkSSpMCiRJEmBSIEmSCpMCSZIEmBRIkqTCpECSJAEmBZIkqTApkCRJgEmBJEkqTAokSRJgUiBJkgqTAkmSBJgUSJKkwqRAkiQBJgWSJKkYcVIQEZMj4rsR8R9l/qiIuCUi7oqIqyJiSinfu8yvKcuPbNjG+0r5jyPipIbyk0vZmog4f88dniRpV3R3d9PS0sKiRYtoaWmhu7u77pA0ipp2oe55QC+wf5n/GPCJzLwyIv4RaAcuLT8fzcyXR8QZpd6bI+Jo4AzglcBhwNci4pfLtj4N/DawHrg1Iq7LzDuf57FJknZBd3c3HR0ddHV10d/fz+TJk2lvbwegra2t5ug0GkbUUhARc4DfAf65zAfwOuCLpcrlwOll+rQyT1m+qNQ/DbgyM5/KzHuANcBx5bUmM+/OzKeBK0tdSdIo6uzspKuri9bWVpqammhtbaWrq4vOzs66Q9MoGWlLwT8A7wH2K/Mzgccys6/Mrwdml+nZwDqAzOyLiMdL/dnAzQ3bbFxn3aDy44cKIiKWAEsAZs2aRU9PzwjD11i2adMm30tpDOjt7eWmm27inHPOYe3atRx++OG0tbXR29vrOTpBDJsURMTvAg9m5u0RsXCgeIiqOcyyHZUP1VqRQ5SRmcuAZQDz58/PhQsXDlVNLzI9PT34Xkr1O+yww7jsssv4/Oc/v6374Mwzz+Swww7zHJ0gRtJS8BvA70fEqcBUqjEF/wAcGBFNpbVgDrCh1F8PzAXWR0QTcACwsaF8QOM6OyqXJI2izNzpvMa3YccUZOb7MnNOZh5JNVDw65l5JrASeEOpthi4tkxfV+Ypy7+e1V/VdcAZ5eqEo4B5wH8BtwLzytUMU8o+rtsjRydJGrENGzZw0UUXsXTpUk466SSWLl3KRRddxIYNfk+bKJ7PfQreC/xFRKyhGjPQVcq7gJml/C+A8wEy8w7gauBO4CvAuZnZX1oa3gncSHV1w9WlriRpFDU3NzNnzhxWr17NihUrWL16NXPmzKG5ubnu0DRKduWSRDKzB+gp03dTXTkwuM4vgDfuYP1O4DnDWDPzBuCGXYlFkrRndXR08OY3v5np06dvG2i4efNmLr744rpD0yjxjoaSpOdwLMHEZFIgSQKq+xRcddVV3HPPPXz961/nnnvu4aqrrvI+BROISYEkCajuU7BgwYLtyhYsWEBvb29NEWm0mRRIkoBqoOGqVau2K1u1apUDDScQkwJJElANNGxvb2flypX09fWxcuVK2tvb6ejoqDs0jZJduvpAkjR+DTz0aOnSpfT29tLc3ExnZ6cPQ5pATAokSdu0tbXR1tbm7ccnKLsPJEkSYFIgSZIKkwJJkgSYFEiSpMKkQJIkASYFkiSpMClQbbq7u2lpaWHRokW0tLTQ3d1dd0iSNKF5nwLVoru7m46ODrq6uujv72fy5Mm0t7cDeKMUSaqJLQWqRWdnJ11dXbS2ttLU1ERraytdXV0+jU2SamRSoFr4NDZJGntMClQLn8YmSWOPSYFq4dPYJGnscaChauHT2CRp7DEpUG18GpskjS12H0iSJMCkQJIkFSYFkiQJMCmQJEmFSYEkSQJMCiRJUjFsUhARUyPivyLi+xFxR0R8sJQfFRG3RMRdEXFVREwp5XuX+TVl+ZEN23pfKf9xRJzUUH5yKVsTEefv+cOUJEnDGUlLwVPA6zLzVcAxwMkRcQLwMeATmTkPeBRoL/XbgUcz8+XAJ0o9IuJo4AzglcDJwP+OiMkRMRn4NHAKcDTQVupKkqRRNGxSkJVNZXav8krgdcAXS/nlwOll+rQyT1m+KCKilF+ZmU9l5j3AGuC48lqTmXdn5tPAlaWuJEkaRSO6o2H5Nn878HKqb/U/AR7LzL5SZT0wu0zPBtYBZGZfRDzyyGXqAAAUTUlEQVQOzCzlNzdstnGddYPKj99BHEuAJQCzZs2ip6dnJOFrjNu0aZPvpTTGeF5OTCNKCjKzHzgmIg4EvgQM9Si7LD9jB8t2VD5Ua0UOUUZmLgOWAcyfPz+9Ne744G2OpbHH83Ji2qWrDzLzMaAHOAE4MCIGkoo5wIYyvR6YC1CWHwBsbCwftM6OyiVJ0igaydUHLyktBETENOC3gF5gJfCGUm0xcG2Zvq7MU5Z/PTOzlJ9Rrk44CpgH/BdwKzCvXM0whWow4nV74uAkSdLIjaT74FDg8jKuYBJwdWb+R0TcCVwZER8Bvgt0lfpdwOciYg1VC8EZAJl5R0RcDdwJ9AHnlm4JIuKdwI3AZGB5Zt6xx45QkiSNyLBJQWb+APj1IcrvprpyYHD5L4A37mBbnUDnEOU3ADeMIF5JkvQC8Y6GkiQJMCmQJEmFSYEkSQJMCiRJUmFSIEmSAJMCSZJUmBRIkiTApECSJBUmBZIkCTApkCRJhUmBJEkCTAokSVJhUiBJkgCTAkmSVJgUSJK26e7upqWlhUWLFtHS0kJ3d3fdIWkUNdUdgCRpbOju7qajo4Ouri76+/uZPHky7e3tALS1tdUcnUaDLQWSJAA6Ozvp6uqitbWVpqYmWltb6erqorOzs+7QNEpMCiRJAPT29rJgwYLtyhYsWEBvb29NEWm0mRRIkgBobm5m1apV25WtWrWK5ubmmiLSaDMpkCQB0NHRQXt7OytXrqSvr4+VK1fS3t5OR0dH3aFplDjQUJIEPDuYcOnSpfT29tLc3ExnZ6eDDCcQkwJJ0jZtbW20tbXR09PDwoUL6w5Ho8zuA0mSBJgUSJKkwqRAkiQBJgWqkbdTlcYez8uJzYGGqoW3U5XGHs9LRWbWHcNumT9/ft522211h6Hd1NLSwumnn84111yz7dKngfnVq1fXHZ40IXlejk8RcXtmzh9J3WFbCiJiLnAF8FJgK7AsMy+OiBnAVcCRwL3AmzLz0YgI4GLgVOBJ4OzM/E7Z1mLg/WXTH8nMy0v5q4HLgGnADcB5+WLNVjQid955J08++eRzvpHce++9dYcmTVh33nknmzdvZvny5dvOy3POOYf77ruv7tA0SkYypqAPeHdmNgMnAOdGxNHA+cCKzJwHrCjzAKcA88prCXApQEkiLgCOB44DLoiIg8o6l5a6A+ud/PwPTWPZlClTeO1rX8vSpUs56aSTWLp0Ka997WuZMmVK3aFJE9aUKVNYunTpdg9EWrp0qeflBLLL3QcRcS3wqfJamJn3R8ShQE9mviIiPlOmu0v9HwMLB16Z+fZS/hmgp7xWZuavlPK2xno7YvfBi1tE0NTUxMc+9jGOPvpo7rzzTt773vfS19eHjURSPSZNmsTBBx/M9OnTWbt2LYcffjibN2/m4YcfZuvWrXWHp920R7sPBm34SODXgVuAWZl5P0BJDA4p1WYD6xpWW1/Kdla+fojyofa/hKpFgVmzZtHT07Mr4WsM2WuvvfjN3/xNLrnkkm3/fBYuXMg3vvEN31epJjNnzmTLli1MmjSJzGTLli1s2bKFmTNnel5OECNOCiJiX+D/AH+WmT+vhg4MXXWIstyN8ucWZi4DlkHVUuAtOF+8+vr6WLNmzXP6Lvv6+ry1qlSTqVOn0tTUxBe+8IVt5+Vb3vIWmpqaPC8niBElBRGxF1VC8PnM/LdS/EBEHNrQffBgKV8PzG1YfQ6woZQvHFTeU8rnDFFf49jRRx/N6aefvt2DV84880yuueaaukOTJqwNGzZw2WWXbXdeXnTRRZx99tl1h6ZRMuxAw3I1QRfQm5kfb1h0HbC4TC8Grm0oPysqJwCPl26GG4ETI+KgMsDwRODGsuyJiDih7Oushm1pnOro6GDZsmVs3rwZgM2bN7Ns2TIf0SrVqLm5mTlz5rB69WpWrFjB6tWrmTNnDs3NzXWHplEykpaC3wD+GPhhRHyvlP01cCFwdUS0A2uBN5ZlN1BdjriG6pLEtwJk5saI+DBwa6n3oczcWKbfwbOXJH65vDRBOLBQGhs6Ojp485vfzPTp07nvvvs44ogj2Lx5MxdffHHdoWmUDJsUZOYqhu73B1g0RP0Ezt3BtpYDy4covw1oGS4WjR+dnZ1cddVVtLa2bntE68qVK1m6dKl3TpPGgJ2MG9M45rMPVIve3l4WLFiwXdmCBQvo7e2tKSJJnZ2dLFmyhOnTpwMwffp0lixZQmdnZ82RabT47APVorm5mVWrVtHa2rqtbNWqVfZdSjW68847eeCBB9h3333JTDZv3sxnPvMZHnnkkbpD0ygxKVAtOjo6aG9v33ab45UrV9Le3u43EqlGkydPpr+/f7tLhV//+tczefLkukPTKDEpUC0Gxg00XvrU2dnpeAKpRn19fWzevJnXve5128qmTJlCX19fjVFpNPmURNVuYKChpHoNDC6cNGkSW7du3fYTvEroxWxXbnPsQEPVpru7m5aWFhYtWkRLSwvd3d11hyQJOOSQQ5g0aRKHHHLI8JU1rth9oFp0d3fT0dHxnEcnA3YhSDWKCB566CG2bt3KQw89RETYSjCB2FKgWnR2dtLV1bXdI1q7urocaCjVrKmpiblz5zJp0iTmzp1LU5PfHScSkwLVwvsUSGPTM888wymnnMK1117LKaecwjPPPFN3SBpFDjRULVpaWjj99NO55pprtl19MDC/evXqusOTJqSI2HZZ4oCB+RfrZ4UcaKgXgdbWVj760Y9uuynKI488wkc/+tHtbmYkaXTNmDFju4QAoL+/nxkzZtQUkUabSYFqcc0117D//vszdepUMpOpU6ey//77++hkqUZPPfXULpVr/DEpUC3Wr1/P1VdfzT333MPXv/517rnnHq6++mrWr19fd2jShDXwKPOXvvSlTJo0iZe+9KXblWv8MymQJG3ztre9jfvvv58VK1Zw//3387a3va3ukDSKHGioWsydO5e+vj6+8IUvbLtPwVve8haamppYt25d3eFJE1JEMH36dF7ykpdw3333ccQRR/DQQw+xefNmBxq+iO3KQEMvQFUtLrroIs477zzOOeecbf98+vv7+fjHP153aNKEFRFs3ryZLVu2kJmsXbuWrVu3brv9scY/uw9Ui7a2Ni6++GKmT5++7dvJxRdf7N0MpRrts88+u1Su8cekQJIEVAMKjz322G1dBZnJscce60DDCcTuA9Wiu7ub8847j+nTpwPVP6PzzjsP8NkHUp02bNjAihUrthvro4nDlgLV4j3veQ9NTU0sX76cG2+8keXL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\n",
"text/plain": "<Figure size 576x432 with 1 Axes>"
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
]
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "data.hist(column=\"ApplicantIncome\",by=\"Loan_Status\",bins=30)",
"execution_count": 41,
"outputs": [
{
"data": {
"text/plain": "array([<matplotlib.axes._subplots.AxesSubplot object at 0x000001BC52607048>,\n <matplotlib.axes._subplots.AxesSubplot object at 0x000001BC52642A58>],\n dtype=object)"
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAX8AAAEcCAYAAAAvJLSTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4xLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvDW2N/gAAFdZJREFUeJzt3Xuw5GV95/H3R5AYiRGQgUUuDol4y1ZEdhbZUJu4ECKXlJCUbLCyMmuRTKpExdVsHN2qsJutbOFeIlq1khqFOFaxgKIWVKRQC3VTbkVkQFRgBGYRYQSG8QKa7CYr8N0/+jeh58yZOb8zc7p/3fO8X1Wn+vTTvz79nWee53P6PP27pKqQJLXlOUMXIEmaPsNfkhpk+EtSgwx/SWqQ4S9JDTL8JalBhr8kNcjwnyFJHkyyLcnBY22/l+TLA5YlTV2Sq5NctaDt15L8IMlRQ9W1PzH8Z8+BwCVDFyEN7B3A2UnOAEjyPOAjwLur6tFBK9tPGP6z578Af5jkkKELkYZSVT8A3g5s6P4SvhT431X1sUEL248Y/rNnE/Bl4A8HrkMaVFV9ErgduAZYB/zBsBXtXwz/2fTHwNuTrBq6EGlgFwOnAX9SVQ8NXcz+xPCfQVV1F/CXwPqha5GGVFXbgO8Ddw9dy/7G8J9dlwK/Dxw9dCGS9j+G/4yqqi3AdYz2epCkFWX4z7Y/AQ5ecitJWqZ4MRdJao/v/CWpQYa/JDXI8JekBhn+ktSgA6f5YocffnitXr16mi+pBtx+++3fr6q5OhrauaBJWM5cmGr4r169mk2bNk3zJdWAJN8duoblci5oEpYzF1z2kaQGGf6S1CDDX5IaZPhLUoMMf0lqkOEvSQ0y/CWpQYa/JDXI8JekBk31CN/lWL3+s7u0PXjZOQNUIg1v4XxwLmhf+c5fkhpk+EtSgwx/SWqQ4S9JDTL8JalBhr8kNcjwl6QGGf6S1CDDX5IaZPhLUoMMf2mBJMcm+VKSzUnuTnJJ135Yki8kub+7PbRrT5IPJdmS5JtJThr2XyAtzfCXdvUU8O6qeiVwCnBxklcB64FbquoE4JbuPsBZwAnd1zrgiumXLC2P4S8tUFWPVtUd3fc/ATYDRwPnAhu7zTYC53Xfnwt8vEa+ChyS5Kgply0ti+Ev7UGS1cBrgFuBI6vqURj9ggCO6DY7Gnh47Glbu7aFP2tdkk1JNm3fvn2SZUtLMvyl3Ujyc8CngHdW1Y/3tOkibbVLQ9WGqlpTVWtWrVq1UmVKe8XwlxaR5LmMgv/qqvp017xtx3JOd/t4174VOHbs6ccAj0yrVmlvGP7SAkkCXAlsrqo/G3voRmBt9/1a4Iax9gu7vX5OAZ7csTwkzaqZvZKXNKBTgTcD30pyZ9f2PuAy4BNJLgIeAs7vHrsJOBvYAvwf4C3TLVdaPsNfWqCqvsLi6/gApy+yfQEXT7QoaYW57CNJDTL8JalBhr8kNcjwl6QGGf6S1KBe4Z/k33RnN7wryTVJnpfk+CS3dmc4vC7JQZMuVpK0MpYM/yRHA+8A1lTVPwYOAC4A3g98oDvD4Y+AiyZZqCRp5fRd9jkQ+NkkBwLPBx4FTgOu7x4fP8OhJGnGLRn+VfU94L8yOqLxUeBJ4Hbgiap6qtts0bMYgmcylKRZ1GfZ51BG5ys/HngxcDCji1cstMtZDMEzGUrSLOqz7PPrwHeqantV/RT4NPArjC5YseP0EJ7FUJLmSJ/wfwg4Jcnzu7Mdng7cA3wJeGO3zfgZDiVJM67Pmv+tjD7YvQP4VvecDcB7gHcl2QK8iNEpcCVJc6DXWT2r6lLg0gXNDwAnr3hFkqSJ8whfSWqQ4S9JDTL8JalBhr8kNcjwl6QGGf6S1CDDX5IaZPhLUoMMf0lqkOEvSQ0y/CWpQYa/JDXI8JekBhn+ktQgw1+SGmT4S1KDDH9JapDhL0kNMvwlqUGGvyQ1yPCXpAYZ/pLUIMNfkhpk+EtSgwx/SWqQ4S8tkOSqJI8nuWus7d8n+V6SO7uvs8cee2+SLUnuTfL6YaqWlsfwl3b1MeDMRdo/UFUndl83ASR5FXAB8Evdcz6c5ICpVSrtJcNfWqCq/gr4Yc/NzwWuraq/r6rvAFuAkydWnLRCDH+pv7cl+Wa3LHRo13Y08PDYNlu7tl0kWZdkU5JN27dvn3St0h4Z/lI/VwC/CJwIPAr8t649i2xbi/2AqtpQVWuqas2qVasmU6XUk+Ev9VBV26rq6ap6BvgIzy7tbAWOHdv0GOCRadcnLZfhL/WQ5Kixu78F7NgT6EbggiQ/k+R44ATga9OuT1quA4cuQJo1Sa4BXgccnmQrcCnwuiQnMlrSeRD4A4CqujvJJ4B7gKeAi6vq6SHqlpbD8JcWqKo3LdJ85R62/1PgTydXkbTyXPaRpAb1Cv8khyS5Psm3k2xO8s+SHJbkC0nu724PXfonSZJmQd93/h8Ebq6qVwCvBjYD64FbquoE4JbuviRpDiwZ/kl+HvhVujXPqvp/VfUEoyMbN3abbQTOm1SRkqSV1eed/y8A24G/SPL1JB9NcjBwZFU9CtDdHjHBOiVJK6hP+B8InARcUVWvAf6WZSzxeEi7JM2ePuG/FdhaVbd2969n9Mtg244DX7rbxxd7soe0S9LsWTL8q+ox4OEkL++aTmd0QMuNwNqubS1ww0QqlCStuL4Heb0duDrJQcADwFsY/eL4RJKLgIeA8ydToiRppfUK/6q6E1izyEOnr2w5kqRp8AhfSWqQ4S9JDTL8JalBhr8kNcjwl6QGGf6S1CDDX5IaZPhLUoMMf0lqkOEvSQ0y/CWpQYa/JDXI8JekBhn+ktQgw1+SGmT4S1KDDH9JapDhL0kNMvwlqUGGvyQ1yPCXpAYZ/pLUIMNfkhp04NAF7LB6/WeHLkGSmuE7f0lqkOEvSQ0y/CWpQYa/JDXI8JekBhn+0gJJrkryeJK7xtoOS/KFJPd3t4d27UnyoSRbknwzyUnDVS71Z/hLu/oYcOaCtvXALVV1AnBLdx/gLOCE7msdcMWUapT2ieEvLVBVfwX8cEHzucDG7vuNwHlj7R+vka8ChyQ5ajqVSnvP8Jf6ObKqHgXobo/o2o8GHh7bbmvXtosk65JsSrJp+/btEy1WWorhL+2bLNJWi21YVRuqak1VrVm1atWEy5L2zPCX+tm2Yzmnu328a98KHDu23THAI1OuTVo2w1/q50Zgbff9WuCGsfYLu71+TgGe3LE8JM2y3uGf5IAkX0/yl93945Pc2u36dl2SgyZXpjQ9Sa4B/hp4eZKtSS4CLgPOSHI/cEZ3H+Am4AFgC/AR4K0DlCwt23LO6nkJsBn4+e7++4EPVNW1Sf4cuAh3c9N+oKretJuHTl9k2wIunmxF0srr9c4/yTHAOcBHu/sBTgOu7zYZ3/VNkjTj+i77XA78EfBMd/9FwBNV9VR3393bJGmOLBn+SX4TeLyqbh9vXmRTd2+TpDnRZ83/VOANSc4Gnsdozf9yRkcyHti9+3f3NkmaI0u+86+q91bVMVW1GrgA+GJV/S7wJeCN3Wbju75Jkmbcvuzn/x7gXUm2MPoM4MqVKUmSNGnLuoB7VX0Z+HL3/QPAyStfkiRp0jzCV5IaZPhLUoMMf0lqkOEvSQ1a1ge+kmbD6vWf3aXtwcvOGaASzSvf+UtSgwx/SWqQ4S9JDTL8JalBhr8kNcjwl6QGGf6S1CDDX5IaZPhLUoMMf0lqkOEvSQ0y/CWpQYa/JDXI8JekBhn+ktQgw1+SGmT4S1KDDH9JapDhL0kNMvwlqUFzdQH3hRet9oLVkrR3fOcvSQ0y/CWpQYa/JDXI8JekBhn+ktSgudrbRxpakgeBnwBPA09V1ZokhwHXAauBB4F/WVU/GqpGqQ/f+UvL9y+q6sSqWtPdXw/cUlUnALd096WZZvhL++5cYGP3/UbgvAFrkXox/KXlKeDzSW5Psq5rO7KqHgXobo8YrDqppyXDP8mxSb6UZHOSu5Nc0rUfluQLSe7vbg+dfLnS4E6tqpOAs4CLk/xq3ycmWZdkU5JN27dvn1yFUg993vk/Bby7ql4JnMJowL8K1znVoKp6pLt9HPgMcDKwLclRAN3t47t57oaqWlNVa1atWjWtkqVFLRn+VfVoVd3Rff8TYDNwNK5zqjFJDk7ygh3fA78B3AXcCKztNlsL3DBMhVJ/y9rVM8lq4DXArSxY50yy6Dpnty66DuC4447bl1qloR0JfCYJjObO/6iqm5PcBnwiyUXAQ8D5+/IiC09gKE1C7/BP8nPAp4B3VtWPuwmwpKraAGwAWLNmTe1NkdIsqKoHgFcv0v4D4PTpVyTtvV57+yR5LqPgv7qqPt0191rnlCTNnj57+wS4EthcVX829pDrnJI0p/os+5wKvBn4VpI7u7b3AZexguuckqTpWTL8q+orwO4W+F3nlKQ55BG+ktQgw1+SGmT4S1KDDH9JapDhL0kNMvwlqUGGvyQ1yPCXpAYZ/pLUIMNfkhq0rPP5S5pdC68D8OBl5wxUieaB7/wlqUGGvyQ1yPCXpAbN9Zr/Ytc6dZ1TkpbmO39JapDhL0kNMvwlqUGGvyQ1yPCXpAYZ/pLUIMNfkho01/v5S9o9j4PRnvjOX5IaZPhLUoP2u2UfT2srSUvznb8kNcjwl6QGGf6S1CDDX5IaZPhLUoMMf0lq0H63q+dCfY9ydBdRtWix+bGQc2H/tN+Hv6Rn9Ql7tcFlH0lq0D6Ff5Izk9ybZEuS9StVlDSPnA+aJ3u97JPkAOC/A2cAW4HbktxYVfesVHGTMs0/fT2z4t6Zt89g5nk+LKXvfJn1/yPtbF/W/E8GtlTVAwBJrgXOBeZ+sEt7wfmwwDTf+Az9C2qS/9ZJ/exU1d49MXkjcGZV/V53/83Aa6vqbQu2Wwes6+6+HLh3kR93OPD9vSpkZVnHzualjpdU1appFbOYPvOh51yA2en3Pqx1Mva21t5zYV/e+WeRtl1+k1TVBmDDHn9Qsqmq1uxDLSvCOqxjHyw5H/rMBZibfy9grZMyjVr35QPfrcCxY/ePAR7Zt3KkueV80FzZl/C/DTghyfFJDgIuAG5cmbKkueN80FzZ62WfqnoqyduAzwEHAFdV1d17+eOW/FN4SqxjZ9bR0346H/qw1smYeK17/YGvJGl+eYSvJDXI8JekBhn+ktSgQc7qmeQVjI5+PJrRvtCPADdW1eYh6pGG4lzQUKb+gW+S9wBvAq5ltG80jPaJvgC4tqoum2pBA3Py76yl/nAuTFZLY2lvDBH+9wG/VFU/XdB+EHB3VZ0wxVpeD5zHzoPjhqq6eUqvP1OT3/6YrlmaC30NPUb6mrexNES/DhH+3wZeX1XfXdD+EuDzVfXyKdVxOfAy4OPsPDguBO6vqkumUMPMTH77Y/pmZS70NQtjpK95GktD9esQa/7vBG5Jcj/wcNd2HPBS4G27fdbKO7uqXrawMcl1wH3ANAbyM8CLge8uaD+qe2ya7I/pm5W50NcsjJG+5mksDdKvUw//qro5ycsYnQL3aEYnxNoK3FZVT0+xlL9LcnJVfW1B+z8F/m5KNczS5Lc/pmyG5kJfszBG+pqnsTRIvzZ7hG+Sk4ArgBfw7J9axwI/Bt5aVbdPqY7nMAOT3/7QUmZljPQ1L2NpqH5t9gLuVXUH8Nok/4ixwVFVj027lLGvZ8Zup1uE/aElzNAY6WsuxtJQ/dps+AMkeSHwa4x9wp7kc1X1xJRe/zeADwP3A9/rmo8BXprkrVX1+WnUMVaP/aE9GnqM9DVvY2mIfm152edC4FLg8+w8OM4A/kNVfXwKNWwGzqqqBxe0Hw/cVFWvnHQNY69pf2iPZmGM9DVPY2mofm05/O9ldJm9Jxa0Hwrcutin7xOo4X7glVX11IL2g4B7quqlk65h7DXtD+3RLIyRvuZpLA3Vry0v+4RFLjvJaE1wsUvyTcJVwG3dxb537JFwLKMDUa6cUg072B9ayiyMkb7maSwN0q8tv/NfC/wxoz+1xncFOwP4j1X1sSnV8SrgDey8R8KNVXXPNF5/rA77Q3s0K2Okr3kZS0P1a7PhD//wZ9Xr2XlwfK6qfjRALYcBNcRrj9Vgf2iPZmmM9DUPY2mIfm06/AGSHMnYJ+xVtW2Kr30c8J+B04Anu+YXAl8E1i/8sGpKNdkf2qMhx0hf8ziWpt2vzYZ/khOBP2c0ILYy+m17DPAEowMr7phCDX8NXA5cv+PAkyQHAOcD76yqUyZdw1gt9of2aBbGSF/zNJYG69eqavILuJPRJ+wL208BvjGlGu7fm8fsD7+G+JqFMbKMWudmLA3Vry3v7XNwVd26sLGqvprk4CnVcHuSDwMb2XmPhLXA16dUww72h5YyC2Okr3kaS4P0a8vLPh8CfpHRaVTHB8eFwHeqauInf+r2Ob6IZy848Q97JABXVtXfT7qGsVrsD+3RLIyRvuZpLA3Vr82GP0CSs1hkcFTVTYMWNhD7Q0txjEzGEP3adPgPLcmBjN6d7HIFH0bvTn66h6fvd+wPrRTH0tKaDf/uRErvZfTb9oiu+XFGg+OymsKJqpJcw+gT/Y3sfAWftcBhVfU7k65hrBb7Q3s0C2Okr3kaS0P1a8vh/zlG+/xurO7Uqd0pVf81cHpVnTGFGu6t3VyqL8l9NcVzpdgfWsosjJG+5mksDdWvz5nED50Tq6vq/TV2zuyqeqxGF3Y+bko1/CjJ+d1FJwBI8pwkvwNM+2hE+0NLmYUx0tc8jaVB+rXl8P9ukj/qjqoDRkfYJXkPz37iPmkXAG8EtiW5rzsT4WPAb3ePTdMs9cdjXX/cx3D9oV3Nwhjpa5bm1lIG6deWl30OBdYzWmc7ktEHQtsY7Qr2/qr64ZTreRGjT/kvr6p/Nc3X7l5/8P7ods97E6MP5u4AzgJ+Bbgb2OCHdMOahTGyN4aeW0sZql+bDX+AJK9g9CHQV6vqb8baz6yqm6fw+jcu0nwao/U/quoNk65hrJbXAt+uqieTPJ/RYDyJUfD+p6p6co8/YGVquJrRacZ/ltH5WA4GPgOczmisrp10DdqzoedMX7M0t5Yy1NxrNvyTvAO4GNgMnAhcUlU3dI/dUVUnTaGGO4B7gI8y+m0f4Bq6P0ur6n9OuoaxWu4GXl1VTyXZAPwt8ClGwfvqqvrtKdTwzar65W43ve8BL66qp5OE0WHuvzzpGrR7szBn+pqlubWUoeZey6d3+H3gn1TV3yRZDVyfZHVVfRCmdmGKNcAlwL8D/m1V3Znk/w40MJ9Tz171aM3YRP5KkjunVUO39HMw8HxGJ7r6IfAzwHOnVIN2bxbmTF+zNLeWMsjcazn8D9jxZ2tVPZjkdYwG80uY0kCuqmeADyT5ZHe7jeH+T+5K8paq+gvgG0nWVNWmJC8DprXWfiXwbeAARpP2k0keYHSCq2unVIN2b/A509eMza2lDDL3Wl72+SLwrqq6c6ztQEaXf/vdqjpggJrOAU6tqvcN8NovBD4I/HPg+4zWHB/uvt5RVd+YUh0vBqiqR5IcAvw68FBVfW0ar6/dm8U509eQc2spQ829lsP/GOCp8X1rxx47tar+1wBlDS7JC4BfYPQuaWvN4IU6NAznzGRNe+41G/6S1LKWD/KSpGYZ/pLUIMNfkhpk+EtSg/4/9ggwEu+/4BUAAAAASUVORK5CYII=\n",
"text/plain": "<Figure size 432x288 with 2 Axes>"
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 10 – Cut function for binning\n\nSometimes numerical values make more sense if clustered together. For example, if we’re trying to model traffic (#cars on road) with time of the day (minutes). The exact minute of an hour might not be that relevant for predicting traffic as compared to actual period of the day like “Morning”, “Afternoon”, “Evening”, “Night”, “Late Night”. Modeling traffic this way will be more intuitive and will avoid overfitting."
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#Binning:\ndef binning(col, cut_points, labels=None):\n #Define min and max values:\n minval = col.min()\n maxval = col.max()\n\n #create list by adding min and max to cut_points\n break_points = [minval] + cut_points + [maxval]\n\n #if no labels provided, use default labels 0 ... (n-1)\n if not labels:\n labels = range(len(cut_points)+1)\n\n #Binning using cut function of pandas\n colBin = pd.cut(col,bins=break_points,labels=labels,include_lowest=True)\n return colBin\n\n#Binning age:\ncut_points = [90,140,190]\nlabels = [\"low\",\"medium\",\"high\",\"very high\"]\ndata[\"LoanAmount_Bin\"] = binning(data[\"LoanAmount\"], cut_points, labels)\nprint(pd.value_counts(data[\"LoanAmount_Bin\"], sort=False))",
"execution_count": 42,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": "low 104\nmedium 266\nhigh 135\nvery high 91\nName: LoanAmount_Bin, dtype: int64\n"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 11 – Coding nominal data\n\nOften, we find a case where we’ve to modify the categories of a nominal variable. This can be due to various reasons:\n\n Some algorithms (like Logistic Regression) require all inputs to be numeric. So nominal variables are mostly coded as 0, 1….(n-1)\n Sometimes a category might be represented in 2 ways. For e.g. temperature might be recorded as “High”, “Medium”, “Low”, “H”, “low”. Here, both “High” and “H” refer to same category. Similarly, in “Low” and “low” there is only a difference of case. But, python would read them as different levels.\n Some categories might have very low frequencies and its generally a good idea to combine them.\n\nHere I’ve defined a generic function which takes in input as a dictionary and codes the values using ‘replace’ function in Pandas."
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#Define a generic function using Pandas replace function\ndef coding(col, codeDict):\n colCoded = pd.Series(col, copy=True)\n for key, value in codeDict.items():\n colCoded.replace(key, value, inplace=True)\n return colCoded\n \n#Coding LoanStatus as Y=1, N=0:\nprint('Before Coding:')\nprint(pd.value_counts(data[\"Loan_Status\"]))\ndata[\"Loan_Status_Coded\"] = coding(data[\"Loan_Status\"], {'N':0,'Y':1})\nprint('After Coding:')\nprint(pd.value_counts(data[\"Loan_Status_Coded\"]))",
"execution_count": 50,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": "Before Coding:\nY 422\nN 192\nName: Loan_Status, dtype: int64\nAfter Coding:\n1 422\n0 192\nName: Loan_Status_Coded, dtype: int64\n"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "# 12 – Iterating over rows of a dataframe\n\nThis is not a frequently used operation. Still, you don’t want to get stuck. Right? At times you may need to iterate through all rows using a for loop. For instance, one common problem we face is the incorrect treatment of variables in Python. This generally happens when:\n\n Nominal variables with numeric categories are treated as numerical.\n Numeric variables with characters entered in one of the rows (due to a data error) are considered categorical.\n\nSo it’s generally a good idea to manually define the column types. If we check the data types of all columns:"
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#Check current type:\ndata.dtypes",
"execution_count": 43,
"outputs": [
{
"data": {
"text/plain": "Gender object\nMarried object\nDependents object\nEducation object\nSelf_Employed object\nApplicantIncome int64\nCoapplicantIncome float64\nLoanAmount float64\nLoan_Amount_Term float64\nCredit_History float64\nProperty_Area object\nLoan_Status object\nLoanAmount_Bin category\ndtype: object"
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Here we see that Credit_History is a nominal variable but appearing as float. A good way to tackle such issues is to create a csv file with column names and types. This way, we can make a generic function to read the file and assign column data types. For instance, here I have created a csv file datatypes.csv."
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#Load the file:\ncolTypes = pd.read_csv('datatypes.csv')\nprint(colTypes)",
"execution_count": 51,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": " feature type\n0 Gender categorical\n1 Married categorical\n2 Dependents categorical\n3 Education categorical\n4 Self_Employed categorical\n5 ApplicantIncome continuous\n6 CoapplicantIncome continuous\n7 LoanAmount continuous\n8 Loan_Amount_Term continuous\n9 Credit_History categorical\n10 Property_Area categorical\n11 Loan_Status categorical\n"
}
]
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "#Iterate through each row and assign variable type.\n#Note: astype is used to assign types\n\nfor i, row in colTypes.iterrows(): #i: dataframe index; row: each row in series format\n if row['type'] == \"categorical\":\n data[row['feature']] = data[row['feature']].astype(np.object)\n elif row['type'] == \"continuous\":\n data[row['feature']] = data[row['feature']].astype(np.float)\nprint(data.dtypes)",
"execution_count": 52,
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": "Gender object\nMarried object\nDependents object\nEducation object\nSelf_Employed object\nApplicantIncome float64\nCoapplicantIncome float64\nLoanAmount float64\nLoan_Amount_Term float64\nCredit_History object\nProperty_Area object\nLoan_Status object\nLoanAmount_Bin category\ndtype: object\n"
}
]
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Now the credit history column is modified to ‘object’ type which is used for representing nominal variables in Pandas."
},
{
"metadata": {
"trusted": false
},
"cell_type": "code",
"source": "",
"execution_count": null,
"outputs": []
}
],
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"language_info": {
"name": "python",
"version": "3.7.1",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
},
"gist": {
"id": "",
"data": {
"description": "12 Useful Panda Techniques.ipynb",
"public": true
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment