{
"cells": [
{
"cell_type": "code",
"execution_count": 62,
"metadata": {
"tags": [
"remove_input"
]
},
"outputs": [],
"source": [
"path_data = '../../data/'\n",
"\n",
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"plt.style.use('fivethirtyeight')\n",
"\n",
"import warnings\n",
"warnings.filterwarnings('ignore')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Applying a Function to a Column\n",
"\n",
"We have seen many examples of creating new columns of tables by applying functions to existing columns or to other arrays. All of those functions took arrays as their arguments. But frequently we will want to convert the entries in a column by a function that doesn't take an array as its argument. For example, it might take just one number as its argument, as in the function `cut_off_at_100` defined below."
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [],
"source": [
"def cut_off_at_100(x):\n",
" \"\"\"The smaller of x and 100\"\"\"\n",
" return min(x, 100)"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"17"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cut_off_at_100(17)"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"100"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cut_off_at_100(117)"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"100"
]
},
"execution_count": 66,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cut_off_at_100(100)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The function `cut_off_at_100` simply returns its argument if the argument is less than or equal to 100. But if the argument is greater than 100, it returns 100.\n",
"\n",
"In our earlier examples using Census data, we saw that the variable `AGE` had a value 100 that meant \"100 years old or older\". Cutting off ages at 100 in this manner is exactly what `cut_off_at_100` does.\n",
"\n",
"To use this function on many ages at once, we will have to be able to *refer* to the function itself, without actually calling it. Analogously, we might show a cake recipe to a chef and ask her to use it to bake 6 cakes. In that scenario, we are not using the recipe to bake any cakes ourselves; our role is merely to refer the chef to the recipe. Similarly, we can ask a table to call `cut_off_at_100` on 6 different numbers in a column."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, we create the table `ages` with a column for people and one for their ages. For example, person `C` is 52 years old."
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Age
\n",
"
\n",
"
\n",
"
Person
\n",
"
\n",
"
\n",
" \n",
" \n",
"
\n",
"
A
\n",
"
17
\n",
"
\n",
"
\n",
"
B
\n",
"
117
\n",
"
\n",
"
\n",
"
C
\n",
"
52
\n",
"
\n",
"
\n",
"
D
\n",
"
100
\n",
"
\n",
"
\n",
"
E
\n",
"
6
\n",
"
\n",
"
\n",
"
F
\n",
"
101
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Age\n",
"Person \n",
"A 17\n",
"B 117\n",
"C 52\n",
"D 100\n",
"E 6\n",
"F 101"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ages = pd.DataFrame(\n",
" {'Person':np.array(['A', 'B', 'C', 'D', 'E', 'F']),\n",
" 'Age':np.array([17, 117, 52, 100, 6, 101])}\n",
")\n",
"ages = ages.set_index('Person')\n",
"ages"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## `map` \n",
"\n",
"To cut off each of the ages at 100, we will use the a new table method. The [`map`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.map.html) method calls a function on each element of a column, forming a new array of return values. To indicate which function to call, just name it (without quotation marks or parentheses). \n",
"\n",
"Pandas [map](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.map.html)"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Person\n",
"A 17\n",
"B 100\n",
"C 52\n",
"D 100\n",
"E 6\n",
"F 100\n",
"Name: Age, dtype: int64"
]
},
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ages['Age'].map(cut_off_at_100)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"What we have done here is `map` the function `cut_off_at_100` to each value in the `Age` column of the table `ages`. The output is the array of corresponding return values of the function. For example, 17 stayed 17, 117 became 100, 52 stayed 52, and so on.\n",
"\n",
"This array, which has the same length as the original `Age` column of the `ages` table, can be used as the values in a new column called `Cut Off Age` alongside the existing `Person` (which has been set as index) and `Age` columns."
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
Age
\n",
"
Cut Off Age
\n",
"
\n",
"
\n",
"
Person
\n",
"
\n",
"
\n",
"
\n",
" \n",
" \n",
"
\n",
"
A
\n",
"
17
\n",
"
17
\n",
"
\n",
"
\n",
"
B
\n",
"
117
\n",
"
100
\n",
"
\n",
"
\n",
"
C
\n",
"
52
\n",
"
52
\n",
"
\n",
"
\n",
"
D
\n",
"
100
\n",
"
100
\n",
"
\n",
"
\n",
"
E
\n",
"
6
\n",
"
6
\n",
"
\n",
"
\n",
"
F
\n",
"
101
\n",
"
100
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Age Cut Off Age\n",
"Person \n",
"A 17 17\n",
"B 117 100\n",
"C 52 52\n",
"D 100 100\n",
"E 6 6\n",
"F 101 100"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ages['Cut Off Age'] = ages['Age'].map(cut_off_at_100)\n",
"ages"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Functions as Values\n",
"We've seen that Python has many kinds of values. For example, `6` is a number value, `\"cake\"` is a text value, `pd.DataFrame({ : })` is an empty table, and `ages` is a name for a table value (since we defined it above).\n",
"\n",
"In Python, every function, including `cut_off_at_100`, is also a value. It helps to think about recipes again. A recipe for cake is a real thing, distinct from cakes or ingredients, and you can give it a name like \"Ani's cake recipe.\" When we defined `cut_off_at_100` with a `def` statement, we actually did two separate things: we created a function that cuts off numbers at 100, and we gave it the name `cut_off_at_100`.\n",
"\n",
"We can refer to any function by writing its name, without the parentheses or arguments necessary to actually call it. We did this when we called `apply` above. When we write a function's name by itself as the last line in a cell, Python produces a text representation of the function, just like it would print out a number or a string value."
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 70,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cut_off_at_100"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice that we did not write `\"cut_off_at_100\"` with quotes (which is just a piece of text), or `cut_off_at_100()` (which is a function call, and an invalid one at that). We simply wrote `cut_off_at_100` to refer to the function.\n",
"\n",
"Just like we can define new names for other values, we can define new names for functions. For example, suppose we want to refer to our function as `cut_off` instead of `cut_off_at_100`. We can just write this:"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [],
"source": [
"cut_off = cut_off_at_100"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now `cut_off` is a name for a function. It's the same function as `cut_off_at_100`, so the printed value is exactly the same."
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cut_off"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us see another application of `map`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Example: Prediction\n",
"Data Science is often used to make predictions about the future. If we are trying to predict an outcome for a particular individual – for example, how they will respond to a treatment, or whether they will buy a product – it is natural to base the prediction on the outcomes of other similar individuals.\n",
"\n",
"Charles Darwin's cousin [Sir Francis Galton](https://en.wikipedia.org/wiki/Francis_Galton) was a pioneer in using this idea to make predictions based on numerical data. He studied how physical characteristics are passed down from one generation to the next.\n",
"\n",
"The data below are Galton's carefully collected measurements on the heights of parents and their adult children. Each row corresponds to one adult child. The variables are a numerical code for the family, the heights (in inches) of the father and mother, a \"midparent height\" which is a weighted average [[1]](#footnotes) of the height of the two parents, the number of children in the family, as well as the child's birth rank (1 = oldest), gender, and height."
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
family
\n",
"
father
\n",
"
mother
\n",
"
midparentHeight
\n",
"
children
\n",
"
childNum
\n",
"
gender
\n",
"
childHeight
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
1
\n",
"
78.5
\n",
"
67.0
\n",
"
75.43
\n",
"
4
\n",
"
1
\n",
"
male
\n",
"
73.2
\n",
"
\n",
"
\n",
"
1
\n",
"
1
\n",
"
78.5
\n",
"
67.0
\n",
"
75.43
\n",
"
4
\n",
"
2
\n",
"
female
\n",
"
69.2
\n",
"
\n",
"
\n",
"
2
\n",
"
1
\n",
"
78.5
\n",
"
67.0
\n",
"
75.43
\n",
"
4
\n",
"
3
\n",
"
female
\n",
"
69.0
\n",
"
\n",
"
\n",
"
3
\n",
"
1
\n",
"
78.5
\n",
"
67.0
\n",
"
75.43
\n",
"
4
\n",
"
4
\n",
"
female
\n",
"
69.0
\n",
"
\n",
"
\n",
"
4
\n",
"
2
\n",
"
75.5
\n",
"
66.5
\n",
"
73.66
\n",
"
4
\n",
"
1
\n",
"
male
\n",
"
73.5
\n",
"
\n",
"
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
\n",
"
\n",
"
929
\n",
"
203
\n",
"
62.0
\n",
"
66.0
\n",
"
66.64
\n",
"
3
\n",
"
1
\n",
"
male
\n",
"
64.0
\n",
"
\n",
"
\n",
"
930
\n",
"
203
\n",
"
62.0
\n",
"
66.0
\n",
"
66.64
\n",
"
3
\n",
"
2
\n",
"
female
\n",
"
62.0
\n",
"
\n",
"
\n",
"
931
\n",
"
203
\n",
"
62.0
\n",
"
66.0
\n",
"
66.64
\n",
"
3
\n",
"
3
\n",
"
female
\n",
"
61.0
\n",
"
\n",
"
\n",
"
932
\n",
"
204
\n",
"
62.5
\n",
"
63.0
\n",
"
65.27
\n",
"
2
\n",
"
1
\n",
"
male
\n",
"
66.5
\n",
"
\n",
"
\n",
"
933
\n",
"
204
\n",
"
62.5
\n",
"
63.0
\n",
"
65.27
\n",
"
2
\n",
"
2
\n",
"
female
\n",
"
57.0
\n",
"
\n",
" \n",
"
\n",
"
934 rows × 8 columns
\n",
"
"
],
"text/plain": [
" family father mother midparentHeight children childNum gender \\\n",
"0 1 78.5 67.0 75.43 4 1 male \n",
"1 1 78.5 67.0 75.43 4 2 female \n",
"2 1 78.5 67.0 75.43 4 3 female \n",
"3 1 78.5 67.0 75.43 4 4 female \n",
"4 2 75.5 66.5 73.66 4 1 male \n",
".. ... ... ... ... ... ... ... \n",
"929 203 62.0 66.0 66.64 3 1 male \n",
"930 203 62.0 66.0 66.64 3 2 female \n",
"931 203 62.0 66.0 66.64 3 3 female \n",
"932 204 62.5 63.0 65.27 2 1 male \n",
"933 204 62.5 63.0 65.27 2 2 female \n",
"\n",
" childHeight \n",
"0 73.2 \n",
"1 69.2 \n",
"2 69.0 \n",
"3 69.0 \n",
"4 73.5 \n",
".. ... \n",
"929 64.0 \n",
"930 62.0 \n",
"931 61.0 \n",
"932 66.5 \n",
"933 57.0 \n",
"\n",
"[934 rows x 8 columns]"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"galton = pd.read_csv(path_data + 'galton.csv')\n",
"\n",
"galton"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A primary reason for collecting the data was to be able to predict the adult height of a child born to parents similar to those in the dataset. Let us try to do this, using midparent height as the variable on which to base our prediction. Thus midparent height is our *predictor* variable.\n",
"\n",
"The table `heights` consists of just the midparent heights and child's heights. The scatter plot of the two variables shows a positive association, as we would expect for these variables."
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"heights.plot.scatter('MidParent', 'Child')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now suppose Galton encountered a new couple, similar to those in his dataset, and wondered how tall their child would be. What would be a good way for him to go about predicting the child's height, given that the midparent height was, say, 68 inches?\n",
"\n",
"One reasonable approach would be to base the prediction on all the points that correspond to a midparent height of around 68 inches. The prediction equals the average child's height calculated from those points alone.\n",
"\n",
"Let's pretend we are Galton and execute this plan. For now we will just make a reasonable definition of what \"around 68 inches\" means, and work with that. Later in the course we will examine the consequences of such choices.\n",
"\n",
"We will take \"close\" to mean \"within half an inch\". The figure below shows all the points corresponding to a midparent height between 67.5 inches and 68.5 inches. These are all the points in the strip between the red lines. Each of these points corresponds to one child; our prediction of the height of the new couple's child is the average height of all the children in the strip. That's represented by the gold dot.\n",
"\n",
"Ignore the code, and just focus on understanding the mental process of arriving at that gold dot."
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"heights.plot.scatter('MidParent','Child')\n",
"_ = plt.plot([67.5, 67.5], [50, 85], color='red', lw=2)\n",
"_ = plt.plot([68.5, 68.5], [50, 85], color='red', lw=2)\n",
"_ = plt.scatter(68, 66.24, color='gold', s=40)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In order to calculate exactly where the gold dot should be, we first need to indentify all the points in the strip. These correspond to the rows where `MidParent` is between 67.5 inches and 68.5 inches."
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
MidParent
\n",
"
Child
\n",
"
\n",
" \n",
" \n",
"
\n",
"
233
\n",
"
68.44
\n",
"
62.0
\n",
"
\n",
"
\n",
"
396
\n",
"
67.94
\n",
"
71.2
\n",
"
\n",
"
\n",
"
397
\n",
"
67.94
\n",
"
67.0
\n",
"
\n",
"
\n",
"
516
\n",
"
68.33
\n",
"
62.5
\n",
"
\n",
"
\n",
"
517
\n",
"
68.23
\n",
"
73.0
\n",
"
\n",
"
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
\n",
"
\n",
"
885
\n",
"
67.60
\n",
"
69.0
\n",
"
\n",
"
\n",
"
886
\n",
"
67.60
\n",
"
68.0
\n",
"
\n",
"
\n",
"
887
\n",
"
67.60
\n",
"
67.7
\n",
"
\n",
"
\n",
"
888
\n",
"
67.60
\n",
"
64.5
\n",
"
\n",
"
\n",
"
889
\n",
"
67.60
\n",
"
60.5
\n",
"
\n",
" \n",
"
\n",
"
131 rows × 2 columns
\n",
"
"
],
"text/plain": [
" MidParent Child\n",
"233 68.44 62.0\n",
"396 67.94 71.2\n",
"397 67.94 67.0\n",
"516 68.33 62.5\n",
"517 68.23 73.0\n",
".. ... ...\n",
"885 67.60 69.0\n",
"886 67.60 68.0\n",
"887 67.60 67.7\n",
"888 67.60 64.5\n",
"889 67.60 60.5\n",
"\n",
"[131 rows x 2 columns]"
]
},
"execution_count": 77,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"close_to_68 = heights[(heights['MidParent'] >= 67.5) & (heights['MidParent'] <= 68.5)]\n",
"close_to_68"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The predicted height of a child who has a midparent height of 68 inches is the average height of the children in these rows. That's 66.24 inches."
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"66.24045801526718"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"close_to_68['Child'].mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We now have a way to predict the height of a child given any value of the midparent height near those in our dataset. We can define a function `predict_child` that does this. The body of the function consists of the code in the two cells above, apart from choices of names."
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [],
"source": [
"def predict_child(mpht):\n",
" \"\"\"Predict the height of a child whose parents have a midparent height of mpht.\n",
" \n",
" The prediction is the average height of the children whose midparent height is\n",
" in the range mpht plus or minus 0.5.\n",
" \"\"\"\n",
" \n",
" close_points = heights[(heights['MidParent'] >= (mpht-0.5)) & (heights['MidParent'] <= (mpht + 0.5))]\n",
" return close_points['Child'].mean() "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Given a midparent height of 68 inches, the function `predict_child` returns the same prediction (66.24 inches) as we got earlier. The advantage of defining the function is that we can easily change the value of the predictor and get a new prediction."
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"66.24045801526718"
]
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"predict_child(68)"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"70.41578947368421"
]
},
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"predict_child(74)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"How good are these predictions? We can get a sense of this by comparing the predictions with the data that we already have. To do this, we first apply the function `predict_child` to the column of `Midparent` heights, and collect the results in a new column called `Prediction`. \n",
"\n",
"In this instance we have used the `map` function, more generally we will use the `applymap` function."
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [],
"source": [
"# Apply predict_child to all the midparent heights\n",
"heights_with_predictions = heights\n",
"\n",
"heights_with_predictions['Prediction'] = heights['MidParent'].map(predict_child)"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"