{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# NumPy Basics: Arrays and Vectorized Computation" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[Errno 2] No such file or directory: '../book_scripts'\n", "/Users/admin/Documents/work/onderwijs/teaching/ISatWork/NoteBooks/pydata-book\n" ] } ], "source": [ "from __future__ import division\n", "from numpy.random import randn\n", "import numpy as np\n", "np.set_printoptions(precision=4, suppress=True)\n", "%cd ../book_scripts" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The NumPy ndarray: a multidimensional array object" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = randn(2, 3)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 0.2195 2.3535 0.3101]\n", " [-0.6689 -0.673 -0.1472]]\n", "[[ 2.1954 23.5353 3.1014]\n", " [ -6.6892 -6.7305 -1.4718]]\n", "[[ 0.4391 4.7071 0.6203]\n", " [-1.3378 -1.3461 -0.2944]]\n" ] } ], "source": [ "print data\n", "print data * 10\n", "print data + data" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "((2, 3), dtype('float64'))" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data.shape,data.dtype" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Creating ndarrays" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data1 = [6, 7.5, 8, 0, 1]\n", "arr1 = np.array(data1)\n", "arr1" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data2 = [[1, 2, 3, 4], [5, 6, 7, 8]]\n", "arr2 = np.array(data2)\n", "arr2\n", "arr2.ndim\n", "arr2.shape" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr1.dtype\n", "arr2.dtype" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[[ 0., 0.],\n", " [ 0., 0.],\n", " [ 0., 0.]],\n", "\n", " [[ 0., 0.],\n", " [ 0., 0.],\n", " [ 0., 0.]]])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.zeros(10)\n", "np.zeros((3, 6))\n", "np.empty((2, 3, 2))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.arange(15)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1., 0., 0., 0., 0.],\n", " [ 0., 1., 0., 0., 0.],\n", " [ 0., 0., 1., 0., 0.],\n", " [ 0., 0., 0., 1., 0.],\n", " [ 0., 0., 0., 0., 1.]])" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.eye(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Data Types for ndarrays" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr1 = np.array([1, 2, 3], dtype=np.float64)\n", "arr2 = np.array([1, 2, 3], dtype=np.int32)\n", "arr1.dtype\n", "arr2.dtype" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.array([1, 2, 3, 4, 5])\n", "arr.dtype\n", "float_arr = arr.astype(np.float64)\n", "float_arr.dtype" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.array([3.7, -1.2, -2.6, 0.5, 12.9, 10.1])\n", "arr\n", "arr.astype(np.int32)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 1.25, -9.6 , 42. ])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "numeric_strings = np.array(['1.25', '-9.6', '42'], dtype=np.string_)\n", "numeric_strings.astype(float)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "int_array = np.arange(10)\n", "calibers = np.array([.22, .270, .357, .380, .44, .50], dtype=np.float64)\n", "int_array.astype(calibers.dtype)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "empty_uint32 = np.empty(8, dtype='u4')\n", "empty_uint32" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Operations between arrays and scalars" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1., 2., 3.],\n", " [ 4., 5., 6.]])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr = np.array([[1., 2., 3.], [4., 5., 6.]])\n", "arr" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1., 4., 9.],\n", " [ 16., 25., 36.]])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr * arr" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0., 0., 0.],\n", " [ 0., 0., 0.]])" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr - arr" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1. , 0.5 , 0.3333],\n", " [ 0.25 , 0.2 , 0.1667]])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "1 / arr" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 1. , 1.4142, 1.7321],\n", " [ 2. , 2.2361, 2.4495]])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr ** 0.5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Basic indexing and slicing" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.arange(10)\n", "arr\n", "arr[5]\n", "arr[5:8]\n", "arr[5:8] = 12\n", "arr" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr_slice = arr[5:8]\n", "arr_slice[1] = 12345\n", "arr\n", "arr_slice[:] = 64\n", "arr" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[1, 2, 3],\n", " [4, 5, 6],\n", " [7, 8, 9]])" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n", "arr2d#[2]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr2d[0][2]\n", "arr2d[0, 2]" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[[ 1, 2, 3],\n", " [ 4, 5, 6]],\n", "\n", " [[ 7, 8, 9],\n", " [10, 11, 12]]])" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])\n", "arr3d" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([7, 8, 9])" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr3d[1,0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "old_values = arr3d[0].copy()\n", "arr3d[0] = 42\n", "arr3d\n", "arr3d[0] = old_values\n", "arr3d" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr3d[1, 0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Indexing with slices" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr[1:6]" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[1, 2, 3],\n", " [4, 5, 6]])" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr2d\n", "arr2d[:2]" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[2, 3],\n", " [5, 6]])" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr2d[:2, 1:]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr2d[1, :2]\n", "arr2d[2, :1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr2d[:, :1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr2d[:2, 1:] = 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Boolean indexing" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])\n", "data = randn(7, 4)\n", "names\n", "data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "names == 'Bob'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data[names == 'Bob']" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data[names == 'Bob', 2:]\n", "data[names == 'Bob', 3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "names != 'Bob'\n", "data[-(names == 'Bob')]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "mask = (names == 'Bob') | (names == 'Will')\n", "mask\n", "data[mask]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data[data < 0] = 0\n", "data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data[names != 'Joe'] = 7\n", "data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Fancy indexing" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0.0000e+000, 0.0000e+000, 7.9051e-323, 0.0000e+000],\n", " [ 0.0000e+000, 2.1403e+161, 5.0462e+180, 4.5062e-144],\n", " [ 7.7995e-143, 7.4496e+020, 4.9237e-062, 4.1060e+020],\n", " [ 1.2003e-071, 2.1639e+190, 3.5777e-052, 1.7237e-042],\n", " [ 7.1175e-038, 1.2500e+016, 4.2768e-096, 9.0837e+223],\n", " [ 4.2576e-096, 6.3230e+233, 6.4822e+170, 5.2241e+257],\n", " [ 2.6554e-312, 0.0000e+000, -1.2882e-231, 0.0000e+000],\n", " [ 1.4822e-323, 0.0000e+000, 0.0000e+000, 2.2251e-308]])" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr = np.empty((8, 4))\n", "arr" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 0., 0., 0., 0.],\n", " [ 1., 1., 1., 1.],\n", " [ 2., 2., 2., 2.],\n", " [ 3., 3., 3., 3.],\n", " [ 4., 4., 4., 4.],\n", " [ 5., 5., 5., 5.],\n", " [ 6., 6., 6., 6.],\n", " [ 7., 7., 7., 7.]])" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for i in range(8):\n", " arr[i] = i\n", "arr" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 4., 4., 4., 4.],\n", " [ 3., 3., 3., 3.],\n", " [ 0., 0., 0., 0.],\n", " [ 6., 6., 6., 6.]])" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr[[4, 3, 0, 6]]" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 5., 5., 5., 5.],\n", " [ 3., 3., 3., 3.],\n", " [ 1., 1., 1., 1.]])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr[[-3, -5, -7]]" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 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", " [24, 25, 26, 27],\n", " [28, 29, 30, 31]])" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# more on reshape in Chapter 12\n", "arr = np.arange(32).reshape((8, 4))\n", "arr" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([ 4, 23, 29, 10])" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr[[1, 5, 7, 2], [0, 3, 1, 2]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr[[1, 5, 7, 2]][:, [0, 3, 1, 2]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr[np.ix_([1, 5, 7, 2], [0, 3, 1, 2])]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Transposing arrays and swapping axes" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.arange(15).reshape((3, 5))\n", "arr\n", "arr.T" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.random.randn(6, 3)\n", "np.dot(arr.T, arr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.arange(16).reshape((2, 2, 4))\n", "arr\n", "arr.transpose((1, 0, 2))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr\n", "arr.swapaxes(1, 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Universal Functions: Fast element-wise array functions" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.arange(10)\n", "np.sqrt(arr)\n", "np.exp(arr)" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 0.9224 0.4169 0.2255 1.4465 -0.5378 -0.3916 2.362 -0.5238]\n", "[-0.3197 -0.8738 0.8344 -0.2029 -1.3528 -0.5517 -0.3809 -0.4375]\n", "[ 0.9224 0.4169 0.8344 1.4465 -0.5378 -0.3916 2.362 -0.4375]\n" ] } ], "source": [ "x = randn(8)\n", "y = randn(8)\n", "print x\n", "print y\n", "print np.maximum(x, y) # element-wise maximum" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = randn(7) * 5\n", "np.modf(arr)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data processing using arrays" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[-5. , -5. , -5. , ..., -5. , -5. , -5. ],\n", " [-4.99, -4.99, -4.99, ..., -4.99, -4.99, -4.99],\n", " [-4.98, -4.98, -4.98, ..., -4.98, -4.98, -4.98],\n", " ..., \n", " [ 4.97, 4.97, 4.97, ..., 4.97, 4.97, 4.97],\n", " [ 4.98, 4.98, 4.98, ..., 4.98, 4.98, 4.98],\n", " [ 4.99, 4.99, 4.99, ..., 4.99, 4.99, 4.99]])" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "points = np.arange(-5, 5, 0.01) # 1000 equally spaced points\n", "xs, ys = np.meshgrid(points, points)\n", "ys" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from matplotlib.pyplot import imshow, title" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "z = np.sqrt(xs ** 2 + ys ** 2)\n", "z\n", "plt.imshow(z, cmap=plt.cm.gray); plt.colorbar()\n", "plt.title(\"Image plot of $\\sqrt{x^2 + y^2}$ for a grid of values\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "plt.draw()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Expressing conditional logic as array operations" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "xarr = np.array([1.1, 1.2, 1.3, 1.4, 1.5])\n", "yarr = np.array([2.1, 2.2, 2.3, 2.4, 2.5])\n", "cond = np.array([True, False, True, True, False])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "result = [(x if c else y)\n", " for x, y, c in zip(xarr, yarr, cond)]\n", "result" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "result = np.where(cond, xarr, yarr)\n", "result" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ True, True, True, False],\n", " [False, False, False, True],\n", " [ True, False, False, True],\n", " [False, False, True, False]], dtype=bool)" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arr = randn(4, 4)\n", "arr >0 " ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 2, 2, 2, -2],\n", " [-2, -2, -2, 2],\n", " [ 2, -2, -2, 2],\n", " [-2, -2, 2, -2]])" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.where(arr > 0, 2, -2)" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ 2. , 2. , 2. , -0.7471],\n", " [-2.3236, -0.3374, -0.4654, 2. ],\n", " [ 2. , -0.0799, -1.2437, 2. ],\n", " [-1.1688, -0.5478, 2. , -1.4399]])" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.where(arr > 0, 2, arr) # set only positive values to 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Not to be executed\n", "\n", "result = []\n", "for i in range(n):\n", " if cond1[i] and cond2[i]:\n", " result.append(0)\n", " elif cond1[i]:\n", " result.append(1)\n", " elif cond2[i]:\n", " result.append(2)\n", " else:\n", " result.append(3)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Not to be executed\n", "\n", "np.where(cond1 & cond2, 0,\n", " np.where(cond1, 1,\n", " np.where(cond2, 2, 3)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Not to be executed\n", "\n", "result = 1 * cond1 + 2 * cond2 + 3 * -(cond1 | cond2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Mathematical and statistical methods" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.random.randn(5, 4) # normally-distributed data\n", "arr.mean()\n", "np.mean(arr)\n", "arr.sum()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr.mean(axis=1)\n", "arr.sum(0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])\n", "arr.cumsum(0)\n", "arr.cumprod(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Methods for boolean arrays" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = randn(100)\n", "(arr > 0).sum() # Number of positive values" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "bools = np.array([False, False, True, False])\n", "bools.any()\n", "bools.all()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Sorting" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = randn(8)\n", "arr\n", "arr.sort()\n", "arr" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = randn(5, 3)\n", "arr\n", "arr.sort(1)\n", "arr" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "large_arr = randn(1000)\n", "large_arr.sort()\n", "large_arr[int(0.05 * len(large_arr))] # 5% quantile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Unique and other set logic" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])\n", " np.unique(names)\n", "ints = np.array([3, 3, 3, 2, 2, 1, 1, 4, 4])\n", "np.unique(ints)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "sorted(set(names))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "values = np.array([6, 0, 0, 3, 2, 5, 6])\n", "np.in1d(values, [2, 3, 6])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## File input and output with arrays" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Storing arrays on disk in binary format" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.arange(10)\n", "np.save('some_array', arr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.load('some_array.npy')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.savez('array_archive.npz', a=arr, b=arr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arch = np.load('array_archive.npz')\n", "arch['b']" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "!rm some_array.npy\n", "!rm array_archive.npz" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Saving and loading text files" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "!cat array_ex.txt" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "arr = np.loadtxt('array_ex.txt', delimiter=',')\n", "arr" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Linear algebra" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "x = np.array([[1., 2., 3.], [4., 5., 6.]])\n", "y = np.array([[6., 23.], [-1, 7], [8, 9]])\n", "x\n", "y\n", "x.dot(y) # equivalently np.dot(x, y)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.dot(x, np.ones(3))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.random.seed(12345)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from numpy.linalg import inv, qr\n", "X = randn(5, 5)\n", "mat = X.T.dot(X)\n", "inv(mat)\n", "mat.dot(inv(mat))\n", "q, r = qr(mat)\n", "r" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Random number generation" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "samples = np.random.normal(size=(4, 4))\n", "samples" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from random import normalvariate\n", "N = 1000000\n", "%timeit samples = [normalvariate(0, 1) for _ in xrange(N)]\n", "%timeit np.random.normal(size=N)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example: Random Walks" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "import random\n", "position = 0\n", "walk = [position]\n", "steps = 1000\n", "for i in xrange(steps):\n", " step = 1 if random.randint(0, 1) else -1\n", " position += step\n", " walk.append(position)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "np.random.seed(12345)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0,\n", " 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1,\n", " 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0,\n", " 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0,\n", " 1, 1, 0, 1, 1, 0, 0, 1])" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nsteps = 1000\n", "draws = np.random.randint(0, 2, size=nsteps)\n", "draws[:100]" ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "collapsed": false }, "outputs": [], "source": [ "steps = np.where(draws > 0, 1, -1)\n", "walk = steps.cumsum()\n", "\n" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pandas as pd\n", "\n", "walkdf=pd.Series(walk)\n", "walkdf.plot();" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(-45, 10)" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "walk.min(),walk.max()" ] }, { "cell_type": "code", "execution_count": 73, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "25" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(np.abs(walk) >= 10).argmax()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Simulating many random walks at once" ] }, { "cell_type": "code", "execution_count": 81, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "array([[ -1, 0, -1, ..., 16, 15, 14],\n", " [ -1, -2, -3, ..., -18, -17, -16],\n", " [ -1, -2, -3, ..., 18, 17, 18],\n", " ..., \n", " [ -1, -2, -1, ..., 6, 5, 6],\n", " [ -1, -2, -1, ..., 50, 51, 52],\n", " [ 1, 2, 1, ..., -32, -31, -30]])" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nwalks = 5000\n", "nsteps = 1000\n", "draws = np.random.randint(0, 2, size=(nwalks, nsteps)) # 0 or 1\n", "steps = np.where(draws > 0, 1, -1)\n", "walks = steps.cumsum(1)\n", "walks" ] }, { "cell_type": "code", "execution_count": 77, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(113, -123)" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "walks.max(),walks.min()" ] }, { "cell_type": "code", "execution_count": 79, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3410" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "hits30 = (np.abs(walks) >= 30).any(1)\n", "hits30\n", "hits30.sum() # Number that hit 30 or -30" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "crossing_times = (np.abs(walks[hits30]) >= 30).argmax(1)\n", "crossing_times.mean()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "steps = np.random.normal(loc=0, scale=0.25,\n", " size=(nwalks, nsteps))" ] } ], "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 }