Files
hands-on/tools_numpy.ipynb
2016-02-18 00:09:50 +01:00

2182 lines
58 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Tools - NumPy\n",
"*NumPy is the fundamental library for scientific computing with Python. NumPy is centered around a powerful N-dimensional array object, and it also contains useful linear algebra, Fourier transform, and random number functions.*\n",
"\n",
"## Creating arrays\n",
"First let's import `numpy`:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import numpy as np"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `zeros` function creates an array containing any number of zeros:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 0. 0. 0. 0. 0.]\n"
]
}
],
"source": [
"print np.zeros(5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It's just as easy to create a 2D array (ie. a matrix) by providing a tuple with the desired number of rows and columns. For example, here's a 3x4 matrix:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0.]]\n"
]
}
],
"source": [
"print np.zeros((3,4))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some vocabulary:\n",
"\n",
"* In NumPy, each dimension is called an **axis**.\n",
"* The number of axes is called the **rank**.\n",
" * For example, the above 3x4 matrix is an array of rank 2 (it is 2-dimensional).\n",
" * The first axis has length 3, the second has length 4.\n",
"* An array's list of axis lengths is called the **shape** of the array.\n",
" * For example, the above matrix's shape is `(3, 4)`.\n",
" * The rank is equal to the shape's length.\n",
"* The **size** of an array is the total number of elements, which is the product of all axis lengths (eg. 3*4=12)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0.]]\n",
"Shape: (3, 4)\n",
"Rank: 2\n",
"Size: 12\n"
]
}
],
"source": [
"a = np.zeros((3,4))\n",
"print a\n",
"print \"Shape:\", a.shape\n",
"print \"Rank:\", a.ndim\n",
"print \"Size:\", a.size"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also create an N-dimensional array of arbitrary rank. For example, here's a 3D array (rank=3), with shape `(2,3,4)`:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[[ 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0.]]\n",
"\n",
" [[ 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0.]]]\n"
]
}
],
"source": [
"print np.zeros((2,3,4))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's look at the type of these arrays:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<type 'numpy.ndarray'>\n"
]
}
],
"source": [
"print type(np.zeros((3,4)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Many other NumPy functions create `ndarrays`.\n",
"\n",
"Here's a 3x4 matrix full of ones:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 1. 1. 1. 1.]\n",
" [ 1. 1. 1. 1.]\n",
" [ 1. 1. 1. 1.]]\n"
]
}
],
"source": [
"print np.ones((3,4))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"An uninitialized 2x3 array (its content is not predictable, as it is whatever is in memory at that point):"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ -1.28822975e-231 -1.28822975e-231 2.17321951e-314]\n",
" [ 2.17322671e-314 -1.28822975e-231 -1.28822975e-231]]\n"
]
}
],
"source": [
"print np.empty((2,3))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Of course you can initialize an `ndarray` using a regular python array (or any iterable). Just call the `array` function:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<type 'numpy.ndarray'>\n",
"[[ 1 2 3 4]\n",
" [10 20 30 40]]\n"
]
}
],
"source": [
"a = np.array([[1,2,3,4], [10, 20, 30, 40]])\n",
"print type(a)\n",
"print a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can create an `ndarray` using NumPy's `range` function, which is similar to python's built-in `range` function:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1 2 3 4]\n"
]
}
],
"source": [
"print np.arange(1, 5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It also works with floats:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 1. 2. 3. 4.]\n"
]
}
],
"source": [
"print np.arange(1.0, 5.0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Of course you can provide a step parameter:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 1. 1.5 2. 2.5 3. 3.5 4. 4.5]\n"
]
}
],
"source": [
"print np.arange(1, 5, 0.5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"However, when dealing with floats, the exact number of elements in the array is not always predictible. For example, consider this:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 0. 0.33333333 0.66666667 1. 1.33333333 1.66666667]\n",
"[ 0. 0.33333333 0.66666667 1. 1.33333333 1.66666667]\n",
"[ 0. 0.33333333 0.66666667 1. 1.33333334]\n"
]
}
],
"source": [
"print np.arange(0, 5/3.0, 1/3.0) # depending on floating point errors, the max value is 4/3.0 or 5/3.0.\n",
"print np.arange(0, 5/3.0, 0.333333333)\n",
"print np.arange(0, 5/3.0, 0.333333334)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For this reason, it is generally preferable to use the `linspace` function instead of `arange` when working with floats. The `linspace` function returns an array containing a specific number of points evenly distributed between two values (note that the maximum value is *included*, contrary to `arange`):"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 0. 0.33333333 0.66666667 1. 1.33333333 1.66666667]\n"
]
}
],
"source": [
"print np.linspace(0, 5/3.0, 6)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A number of functions are available in NumPy's `random` module to create `ndarray`s initialized with random values.\n",
"For example, here is a 3x4 matrix initialized with random floats between 0 and 1 (uniform distribution):"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0.31505455 0.75655077 0.15133163 0.61991085]\n",
" [ 0.42809672 0.56288807 0.74871884 0.55155697]\n",
" [ 0.5127511 0.65383425 0.13132709 0.79646256]]\n"
]
}
],
"source": [
"print np.random.rand(3,4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here's a 3x4 matrix containing random floats sampled from a univariate [normal distribution](https://en.wikipedia.org/wiki/Normal_distribution) (Gaussian distribution) of mean 0 and variance 1:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0.10283232 1.73246206 -0.06356761 -0.07068949]\n",
" [ 1.61004733 0.12150407 -1.26750323 0.97991332]\n",
" [ 0.32727099 -0.86810473 -1.12277424 1.39791034]]\n"
]
}
],
"source": [
"print np.random.randn(3,4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To give you a feel of what these distributions look like, let's use matplotlib (see the [matplotlib tutorial](tools_matplotlib.ipynb) for more details):"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"data": {
"image/png": "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\nEYmp/w+456/1tPn2TgAAAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1055903d0>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"import matplotlib.pyplot as plt\n",
"plt.hist(np.random.rand(100000), normed=True, bins=100, histtype=\"step\", color=\"blue\", label=\"rand\")\n",
"plt.hist(np.random.randn(100000), normed=True, bins=100, histtype=\"step\", color=\"red\", label=\"randn\")\n",
"plt.axis([-2.5, 2.5, 0, 1.1])\n",
"plt.legend(loc = \"upper left\")\n",
"plt.title(\"Random distributions\")\n",
"plt.xlabel(\"Value\")\n",
"plt.ylabel(\"Density\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also initialize an `ndarray` using a function:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
" [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]]\n",
"\n",
" [[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]\n",
" [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]]\n",
"\n",
" [[ 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.]\n",
" [ 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.]]]\n"
]
}
],
"source": [
"def my_function(z, y, x):\n",
" return x * y + z\n",
"\n",
"print np.fromfunction(my_function, (3, 2, 10))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"NumPy first creates three `ndarrays` (one per dimension), each of shape `(3, 2, 10)`. Each array has values equal to the coordinate along a specific axis. For example, all elements in the `z` array are equal to the z-coordinate:\n",
"\n",
" [[[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
" [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]\n",
" \n",
" [[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]\n",
" [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]]\n",
" \n",
" [[ 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.]\n",
" [ 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.]]]\n",
"\n",
"This means that `my_function` is only called once, so the initialization is very efficient."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Array data\n",
"NumPy's `ndarray`s are very efficient in part because all their elements must have the same type (usually numbers).\n",
"You can check what the data type is by looking at the `dtype` attribute:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"int64 [1 2 3 4]\n",
"float64 [ 1. 2. 3. 4.]\n"
]
}
],
"source": [
"a = np.arange(1, 5)\n",
"print a.dtype, a\n",
"\n",
"b = np.arange(1.0, 5.0)\n",
"print b.dtype, b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Instead of letting NumPy guess what data type to use, you can set it explicitly when creating an array by setting the `dtype` parameter:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"complex64 [ 1.+0.j 2.+0.j 3.+0.j 4.+0.j]\n"
]
}
],
"source": [
"a = np.arange(1, 5, dtype=np.complex64)\n",
"print a.dtype, a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Available data types include int8, int16, int32, int64, uint8/16/32/64, float16/32/64 and complex64/128. Check out [the documentation](http://docs.scipy.org/doc/numpy-1.10.1/user/basics.types.html) for the full list.\n",
"\n",
"The `itemsize` attribute returns the size (in bytes) of each item:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"8\n"
]
}
],
"source": [
"a = np.arange(1, 5, dtype=np.complex64)\n",
"print a.itemsize"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"An array's data is actually stored in memory as a flat (one dimensional) byte buffer. It is available *via* the `data` attribute (you will rarely need it, though)."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Array:\n",
"[[ 1 2]\n",
" [1000 2000]]\n",
"Raw data:\n",
"[1, 0, 0, 0, 2, 0, 0, 0, 232, 3, 0, 0, 208, 7, 0, 0]\n"
]
}
],
"source": [
"a = np.array([[1,2],[1000, 2000]], dtype=np.int32)\n",
"print \"Array:\"\n",
"print a\n",
"print \"Raw data:\"\n",
"print [ord(c) for c in a.data]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Several `ndarrays` can share the same data buffer, meaning that modifying one will also modify the others. We will see an example in a minute."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Reshaping an array\n",
"Changing the shape of an `ndarray` is as simple as setting its `shape` attribute. However, the array's size must remain the same."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]\n",
"Rank: 1\n"
]
}
],
"source": [
"a = np.arange(24)\n",
"print a\n",
"print \"Rank:\", a.ndim"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0 1 2 3]\n",
" [ 4 5 6 7]\n",
" [ 8 9 10 11]\n",
" [12 13 14 15]\n",
" [16 17 18 19]\n",
" [20 21 22 23]]\n",
"Rank: 2\n"
]
}
],
"source": [
"a.shape = (6, 4)\n",
"print a\n",
"print \"Rank:\", a.ndim"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[[ 0 1 2 3]\n",
" [ 4 5 6 7]\n",
" [ 8 9 10 11]]\n",
"\n",
" [[12 13 14 15]\n",
" [16 17 18 19]\n",
" [20 21 22 23]]]\n",
"Rank: 3\n"
]
}
],
"source": [
"a.shape = (2, 3, 4)\n",
"print a\n",
"print \"Rank:\", a.ndim"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `reshape` function returns a new `ndarray` object pointing to the *same* data. This means that modifying one array will also modify the other."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0 1 2 3 4 5]\n",
" [ 6 7 8 9 10 11]\n",
" [12 13 14 15 16 17]\n",
" [18 19 20 21 22 23]]\n",
"Rank: 2\n"
]
}
],
"source": [
"a2 = a.reshape(4,6)\n",
"print a2\n",
"print \"Rank:\", a2.ndim"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Set item at row 1, col 2 to 999 (more about indexing below)."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0 1 2 3 4 5]\n",
" [ 6 7 999 9 10 11]\n",
" [ 12 13 14 15 16 17]\n",
" [ 18 19 20 21 22 23]]\n"
]
}
],
"source": [
"a2[1, 2] = 999\n",
"print a2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The corresponding element in a has been modified."
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[[ 0 1 2 3]\n",
" [ 4 5 6 7]\n",
" [999 9 10 11]]\n",
"\n",
" [[ 12 13 14 15]\n",
" [ 16 17 18 19]\n",
" [ 20 21 22 23]]]\n"
]
}
],
"source": [
"print a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, the `ravel` function returns a new one-dimensional `ndarray` that also points to the same data:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 0 1 2 3 4 5 6 7 999 9 10 11 12 13 14 15 16 17\n",
" 18 19 20 21 22 23]\n"
]
}
],
"source": [
"a3 = a.ravel()\n",
"print a3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Array indexing\n",
"One-dimensional NumPy arrays can be accessed more or less like regular python arrays:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"19\n"
]
}
],
"source": [
"a = np.array([1, 5, 3, 19, 13, 7, 3])\n",
"print a[3]"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 3 19 13]\n"
]
}
],
"source": [
"print a[2:5]"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 3 19 13 7]\n"
]
}
],
"source": [
"print a[2:-1]"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1 5]\n"
]
}
],
"source": [
"print a[:2]"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 3 13 3]\n"
]
}
],
"source": [
"print a[2::2]"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 3 7 13 19 3 5 1]\n"
]
}
],
"source": [
"print a[::-1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Of course, you can modify elements:"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 1 5 3 999 13 7 3]\n"
]
}
],
"source": [
"a[3]=999\n",
"print a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also modify an `ndarray` slice:"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 1 5 997 998 999 7 3]\n"
]
}
],
"source": [
"a[2:5] = [997, 998, 999]\n",
"print a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And if you assign a single value, it is copied across the whole slice (this is called *broadcasting*, more on this below):"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 1 5 -1 -1 -1 7 3]\n"
]
}
],
"source": [
"a[2:5] = -1\n",
"print a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Contrary to regular python arrays, you cannot grow or shrink `ndarray`s this way:"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"cannot copy sequence with size 6 to array axis with dimension 3\n"
]
}
],
"source": [
"try:\n",
" a[2:5] = [1,2,3,4,5,6] # too long\n",
"except ValueError, e:\n",
" print e"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You cannot delete elements either:"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"cannot delete array elements\n"
]
}
],
"source": [
"try:\n",
" del a[2:5]\n",
"except ValueError, e:\n",
" print e"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Multi-dimensional arrays can be accessed in a similar way by providing an index or slice for each axis, separated by commas:"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0 1 2 3 4 5 6 7 8 9 10 11]\n",
" [12 13 14 15 16 17 18 19 20 21 22 23]\n",
" [24 25 26 27 28 29 30 31 32 33 34 35]\n",
" [36 37 38 39 40 41 42 43 44 45 46 47]]\n"
]
}
],
"source": [
"b = np.arange(48).reshape(4, 12)\n",
"print b"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"14\n"
]
}
],
"source": [
"print b[1, 2] # row 1, col 2"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[12 13 14 15 16 17 18 19 20 21 22 23]\n"
]
}
],
"source": [
"print b[1, :] # row 1, all columns"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 1 13 25 37]\n"
]
}
],
"source": [
"print b[:, 1] # all rows, column 1"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 2 3 4]\n",
" [26 27 28]]\n"
]
}
],
"source": [
"print b[(0,2), 2:5] # rows 0 and 2, columns 2 to 4 (5-1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also provide an `ndarray` of boolean values to specify the indices that you want to access. This will come in handy later:"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0 1 2 3 4 5 6 7 8 9 10 11]\n",
" [24 25 26 27 28 29 30 31 32 33 34 35]]\n"
]
}
],
"source": [
"bools = np.array([True, False, True, False])\n",
"print b[bools, :] # Rows 0 and 2, all columns. Equivalent to b[(1, 3), :]"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 1 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46]\n"
]
}
],
"source": [
"print b[b % 3 == 1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note the subtle difference between these two expressions: "
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[12 13 14 15 16 17 18 19 20 21 22 23]\n",
"[[12 13 14 15 16 17 18 19 20 21 22 23]]\n"
]
}
],
"source": [
"print b[1, :]\n",
"print b[1:2, :]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The first expression returns row 1 as a 1D array of shape `(12,)`, while the second returns that same row as a 2D array of shape `(1, 12)`."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Everything works just as well with higher dimension arrays:"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[[ 0 1 2 3 4 5]\n",
" [ 6 7 8 9 10 11]]\n",
"\n",
" [[12 13 14 15 16 17]\n",
" [18 19 20 21 22 23]]\n",
"\n",
" [[24 25 26 27 28 29]\n",
" [30 31 32 33 34 35]]\n",
"\n",
" [[36 37 38 39 40 41]\n",
" [42 43 44 45 46 47]]]\n"
]
}
],
"source": [
"c = b.reshape(4,2,6)\n",
"print c"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"34\n"
]
}
],
"source": [
"print c[2, 1, 4] # matrix 2, row 1, col 4"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[27 33]\n"
]
}
],
"source": [
"print c[2, :, 3] # matrix 2, all rows, col 3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you omit coordinates for some axes, then all elements in these axes are returned:"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[30 31 32 33 34 35]\n"
]
}
],
"source": [
"print c[2, 1] # Return matrix 2, row 1, all columns. This is equivalent to c[2, 1, :]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You may also write an ellipsis (`...`) to specify that all non-specified axes must be entirely included."
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[24 25 26 27 28 29]\n",
" [30 31 32 33 34 35]]\n"
]
}
],
"source": [
"print c[2, ...] # matrix 2, all rows, all columns. This is equivalent to c[2, :, :]"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[30 31 32 33 34 35]\n"
]
}
],
"source": [
"print c[2, 1, ...] # matrix 2, row 1, all columns. This is equivalent to c[2, 1, :]"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[27 33]\n"
]
}
],
"source": [
"print c[2, ..., 3] # matrix 2, all rows, column 3. This is equivalent to c[2, :, 3]"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 3 9]\n",
" [15 21]\n",
" [27 33]\n",
" [39 45]]\n"
]
}
],
"source": [
"print c[..., 3] # all matrices, all rows, column 3. This is equivalent to c[:, :, 3]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Broadcasting"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As we discussed above, assigning to an `ndarray` slice requires an `ndarray` of the same shape as the slice. In general, when NumPy expects arrays of the same shape but finds that this is not the case, it applies the so-called *broadcasting* rules:\n",
"\n",
"**First rule**: if the arrays do not have the same rank, then a 1 will be prepended to the smaller ranking arrays until their ranks match.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[[0 1 2 3 4 5 6 7 8 9]]]\n"
]
}
],
"source": [
"a = np.arange(10).reshape(1, 1, 10)\n",
"print a"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Slice: [[[2 3]]]\n",
"Shape: (1, 1, 2)\n"
]
}
],
"source": [
"print \"Slice:\", a[..., 2:4]\n",
"print \"Shape:\", a[..., 2:4].shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's try to assign a 1D array of shape `(2,)` to this 3D array of shape `(1,1,2)`. Applying the first rule of broadcasting!"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[[ 0 1 55 66 4 5 6 7 8 9]]]\n"
]
}
],
"source": [
"a[..., 2:4] = [55, 66] # acts as [[[55, 56]]]\n",
"print a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Second rule**: arrays with a 1 along a particular dimension act as if they had the size of the array with the largest shape along that dimension. The value of the array element is repeated along that dimension."
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[0 1 2 3 4]\n",
" [5 6 7 8 9]]\n"
]
}
],
"source": [
"b = np.arange(10).reshape(2, 5)\n",
"print b"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Slice:\n",
"[[1 2 3]\n",
" [6 7 8]]\n",
"Shape: (2, 3)\n"
]
}
],
"source": [
"print \"Slice:\"\n",
"print b[..., 1:4]\n",
"print \"Shape:\", b[..., 1:4].shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's try to assign a 2D array of shape `(2,1)` to this slice of shape `(2, 3)`. NumPy will apply the second rule of broadcasting:"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0 44 44 44 4]\n",
" [ 5 55 55 55 9]]\n"
]
}
],
"source": [
"b[..., 1:4] = [[44], [55]] # acts as [[44, 44, 44], [55, 55, 55]]\n",
"print b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Combining rules 1 & 2, we can do this:"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0 66 77 88 4]\n",
" [ 5 66 77 88 9]]\n"
]
}
],
"source": [
"b[..., 1:4] = [66, 77, 88] # after rule 1: [[66, 77, 88]], and after rule 2: [[66, 77, 88], [66, 77, 88]]\n",
"print b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And also, very simply:"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0 99 99 99 4]\n",
" [ 5 99 99 99 9]]\n"
]
}
],
"source": [
"b[..., 1:4] = 99 # after rule 1: [[99]], and after rule 2: [[99, 99, 99], [99, 99, 99]]\n",
"print b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Third rule**: after rules 1 & 2, the sizes of all arrays must match."
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"could not broadcast input array from shape (2) into shape (2,3)\n"
]
}
],
"source": [
"try:\n",
" b[..., 1:4] = [33, 44]\n",
"except ValueError, e:\n",
" print e"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Broadcasting rules are used in many NumPy operations, not just assignment, as we will see below.\n",
"For more details about broadcasting, check out [the documentation](https://docs.scipy.org/doc/numpy-dev/user/basics.broadcasting.html)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Iterating\n",
"Iterating over `ndarray`s is very similar to iterating over regular python arrays. Note that iterating over multidimensional arrays is done with respect to the first axis."
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[[ 0 1 2 3 4 5]\n",
" [ 6 7 8 9 10 11]]\n",
"\n",
" [[12 13 14 15 16 17]\n",
" [18 19 20 21 22 23]]]\n"
]
}
],
"source": [
"c = np.arange(24).reshape(2, 2, 6) # A 3D array (composed of two 2x6 matrices)\n",
"print c"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Item:\n",
"[[ 0 1 2 3 4 5]\n",
" [ 6 7 8 9 10 11]]\n",
"Item:\n",
"[[12 13 14 15 16 17]\n",
" [18 19 20 21 22 23]]\n"
]
}
],
"source": [
"for m in c:\n",
" print \"Item:\"\n",
" print m"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Item:\n",
"[[ 0 1 2 3 4 5]\n",
" [ 6 7 8 9 10 11]]\n",
"Item:\n",
"[[12 13 14 15 16 17]\n",
" [18 19 20 21 22 23]]\n"
]
}
],
"source": [
"for i in range(len(c)): # Note that len(c) == c.shape[0]\n",
" print \"Item:\"\n",
" print c[i]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you want to iterate on *all* elements in the `ndarray`, simply iterate over the `flat` attribute:"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Item: 0\n",
"Item: 1\n",
"Item: 2\n",
"Item: 3\n",
"Item: 4\n",
"Item: 5\n",
"Item: 6\n",
"Item: 7\n",
"Item: 8\n",
"Item: 9\n",
"Item: 10\n",
"Item: 11\n",
"Item: 12\n",
"Item: 13\n",
"Item: 14\n",
"Item: 15\n",
"Item: 16\n",
"Item: 17\n",
"Item: 18\n",
"Item: 19\n",
"Item: 20\n",
"Item: 21\n",
"Item: 22\n",
"Item: 23\n"
]
}
],
"source": [
"for i in c.flat:\n",
" print \"Item:\", i"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Arithmetic operations\n",
"All the usual arithmetic operators (`+`, `-`, `*`, `/`, `**`, etc.) can be used with `ndarray`s. They apply elementwise:"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"a + b = [19 27 35 43]\n",
"a - b = [ 9 19 29 39]\n",
"a * b = [70 92 96 82]\n",
"a / b = [ 2 5 10 20]\n",
"a % b = [4 3 2 1]\n",
"a ** b = [537824 279841 32768 1681]\n"
]
}
],
"source": [
"a = np.array([14, 23, 32, 41])\n",
"b = np.array([5, 4, 3, 2])\n",
"print \"a + b =\", a + b\n",
"print \"a - b =\", a - b\n",
"print \"a * b =\", a * b\n",
"print \"a / b =\", a / b\n",
"print \"a % b =\", a % b\n",
"print \"a ** b =\", a ** b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that the multiplication is *not* a matrix multiplication. We will discuss matrix operations below.\n",
"\n",
"The arrays must have the same shape. If they do not, NumPy will apply the broadcasting rules, as discussed above."
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 42 69 96 123]\n"
]
}
],
"source": [
"print a * 3 # thanks to broadcasting, this is equivalent to: a * [3, 3, 3, 3]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The conditional operators also apply elementwise:"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ True False True False]\n"
]
}
],
"source": [
"print a < [15, 16, 35, 36]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And using broadcasting:"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ True True False False]\n"
]
}
],
"source": [
"print a < 25 # equivalent to a < [25, 25, 25, 25]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is most useful in conjunction with boolean indexing:"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[14 23]\n"
]
}
],
"source": [
"print a[a < 25]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that all matching elements are returned as a 1D array, no matter the original array's shape:"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0. 0. 0. 0. 0. 0.]\n",
" [ 0. 1. 2. 3. 4. 5.]\n",
" [ 0. 2. 4. 6. 8. 10.]]\n"
]
}
],
"source": [
"p = np.fromfunction(lambda row, col: row*col, (3,6))\n",
"print p"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 1. 4. 4. 10.]\n"
]
}
],
"source": [
"print p[p%3 == 1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is possible (and quite convenient) to use boolean indexing and assignment jointly:"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 0. 0. 0. 0. 0. 0.]\n",
" [ 0. 99. 2. 3. 99. 5.]\n",
" [ 0. 2. 99. 6. 8. 99.]]\n"
]
}
],
"source": [
"p[p%3 == 1] = 99\n",
"print p"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## To be continued..."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.10"
}
},
"nbformat": 4,
"nbformat_minor": 0
}