{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"\n",
"*This notebook contains an excerpt from the [Python Data Science Handbook](http://shop.oreilly.com/product/0636920034919.do) by Jake VanderPlas; the content is available [on GitHub](https://github.com/jakevdp/PythonDataScienceHandbook).*\n",
"\n",
"*The text is released under the [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/us/legalcode), and code is released under the [MIT license](https://opensource.org/licenses/MIT). If you find this content useful, please consider supporting the work by [buying the book](http://shop.oreilly.com/product/0636920034919.do)!*\n",
"\n",
"*No changes were made to the contents of this notebook from the original.*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"< [Comparisons, Masks, and Boolean Logic](02.06-Boolean-Arrays-and-Masks.ipynb) | [Contents](Index.ipynb) | [Sorting Arrays](02.08-Sorting.ipynb) >"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Fancy Indexing"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the previous sections, we saw how to access and modify portions of arrays using simple indices (e.g., ``arr[0]``), slices (e.g., ``arr[:5]``), and Boolean masks (e.g., ``arr[arr > 0]``).\n",
"In this section, we'll look at another style of array indexing, known as *fancy indexing*.\n",
"Fancy indexing is like the simple indexing we've already seen, but we pass arrays of indices in place of single scalars.\n",
"This allows us to very quickly access and modify complicated subsets of an array's values."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Exploring Fancy Indexing\n",
"\n",
"Fancy indexing is conceptually simple: it means passing an array of indices to access multiple array elements at once.\n",
"For example, consider the following array:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[51 92 14 71 60 20 82 86 74 74]\n"
]
}
],
"source": [
"import numpy as np\n",
"rand = np.random.RandomState(42)\n",
"\n",
"x = rand.randint(100, size=10)\n",
"print(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Suppose we want to access three different elements. We could do it like this:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[71, 86, 14]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"[x[3], x[7], x[2]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Alternatively, we can pass a single list or array of indices to obtain the same result:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([71, 86, 60])"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ind = [3, 7, 4]\n",
"x[ind]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"When using fancy indexing, the shape of the result reflects the shape of the *index arrays* rather than the shape of the *array being indexed*:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[71, 86],\n",
" [60, 20]])"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ind = np.array([[3, 7],\n",
" [4, 5]])\n",
"x[ind]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Fancy indexing also works in multiple dimensions. Consider the following array:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 0, 1, 2, 3],\n",
" [ 4, 5, 6, 7],\n",
" [ 8, 9, 10, 11]])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X = np.arange(12).reshape((3, 4))\n",
"X"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Like with standard indexing, the first index refers to the row, and the second to the column:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ 2, 5, 11])"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"row = np.array([0, 1, 2])\n",
"col = np.array([2, 1, 3])\n",
"X[row, col]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Notice that the first value in the result is ``X[0, 2]``, the second is ``X[1, 1]``, and the third is ``X[2, 3]``.\n",
"The pairing of indices in fancy indexing follows all the broadcasting rules that were mentioned in [Computation on Arrays: Broadcasting](02.05-Computation-on-arrays-broadcasting.ipynb).\n",
"So, for example, if we combine a column vector and a row vector within the indices, we get a two-dimensional result:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 2, 1, 3],\n",
" [ 6, 5, 7],\n",
" [10, 9, 11]])"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X[row[:, np.newaxis], col]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here, each row value is matched with each column vector, exactly as we saw in broadcasting of arithmetic operations.\n",
"For example:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0, 0, 0],\n",
" [2, 1, 3],\n",
" [4, 2, 6]])"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"row[:, np.newaxis] * col"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is always important to remember with fancy indexing that the return value reflects the *broadcasted shape of the indices*, rather than the shape of the array being indexed."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Combined Indexing\n",
"\n",
"For even more powerful operations, fancy indexing can be combined with the other indexing schemes we've seen:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0 1 2 3]\n",
" [ 4 5 6 7]\n",
" [ 8 9 10 11]]\n"
]
}
],
"source": [
"print(X)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can combine fancy and simple indices:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([10, 8, 9])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X[2, [2, 0, 1]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can also combine fancy indexing with slicing:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 6, 4, 5],\n",
" [10, 8, 9]])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X[1:, [2, 0, 1]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And we can combine fancy indexing with masking:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 0, 2],\n",
" [ 4, 6],\n",
" [ 8, 10]])"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mask = np.array([1, 0, 1, 0], dtype=bool)\n",
"X[row[:, np.newaxis], mask]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All of these indexing options combined lead to a very flexible set of operations for accessing and modifying array values."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Example: Selecting Random Points\n",
"\n",
"One common use of fancy indexing is the selection of subsets of rows from a matrix.\n",
"For example, we might have an $N$ by $D$ matrix representing $N$ points in $D$ dimensions, such as the following points drawn from a two-dimensional normal distribution:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(100, 2)"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mean = [0, 0]\n",
"cov = [[1, 2],\n",
" [2, 5]]\n",
"X = rand.multivariate_normal(mean, cov, 100)\n",
"X.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using the plotting tools we will discuss in [Introduction to Matplotlib](04.00-Introduction-To-Matplotlib.ipynb), we can visualize these points as a scatter-plot:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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WD0nJ8etZgFdbNiwQbfccovGjh2rhx9+2O3mOC4tgkhWVpaGDx8e8etffPGFtm7dqgsvvLDts5ycHA0ePFjV1dU90cSkE6tPwxYvXqzly5drzpw5uuOOO5jqisBqfyJ+4ZHN6upqDRkypO3z6upqRungGc8//7zuv/9+zZw5U4sXL+4ygpeKWKwq6bPPPtONN96ovXv3tn1WX1+vXbt28XJIwKJFi7R8+XItXLhQd955JyEEriovL1efPn20cePGts/q6+u1bds2TZw40cWWASesXLlS9957ry6//HI98sgjaRFCpDQZEYnl3HPPVVlZmRYuXKi77rpLoVBIixYtUkFBgb7//e+73byktHHjRj399NOaM2eOLrnkEh04cKDtayeddJJyc3NdbB3SUa9evXTFFVdo8eLFKiws1KBBg7Ro0SINGDBAM2fOdLt5SHO7du3SL37xC82cOVPXXnutDh482Pa13r17Ky8vz8XWOYsgohP/gXr66af14IMPat68eTp27JimTp2qBx54QH369HG7eUkpvO99xYoVWrFiRYevXX/99brhhhvcaBbS3I033qiWlhbdeeedampq0qRJk/TMM8+kzW+e8K5169bp+PHjWr9+fZe6NrNmzdIDDzzgUsuc5wtROhQAALiENSIAAMA1BBEAAOAagggAAHANQQQAALiGIAIAAFxDEAEAAK4hiAAAANcQRAAAgGsIIgAAwDUEEQAA4BqCCAAAcM3/By7JEwZLdABBAAAAAElFTkSuQmCC\n",
"text/plain": [
"