{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to NumPy (numeric Python) for the Image processing class" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## NumPy, SciPy (Scientific Python) and MatPlotLib (Mathematic plotting library) = replacement of Matlab " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Numpy is not native, hence we need to import it:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Numpy implements nd-arrays (which can be images)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "a = np.zeros((2,3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "shape and dtype " ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(2, 3)\n", "float64\n" ] }, { "data": { "text/plain": [ "array([[0., 0., 0.],\n", " [0., 0., 0.]])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(a.shape)\n", "print(a.dtype)\n", "a" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1.],\n", " [1.]])" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.ones((2,1))\n", "a" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1],\n", " [1]])" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.ones((2,1),dtype=int)\n", "a" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[7., 7.],\n", " [7., 7.]])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.full((2,2),7.)\n", "a" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 0., 0.],\n", " [0., 1., 0.],\n", " [0., 0., 1.]])" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.eye(3) # identity matrix\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create random numbers between 0 and 1" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0.55138052, 0.33165654],\n", " [0.94713208, 0.96812048],\n", " [0.87842363, 0.83266018]])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.random.random((3,2))\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and Gaussian random numbers with std=1 and mean = 0" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.15391407, -0.14134898],\n", " [-1.51905937, 0.55790291],\n", " [ 0.21843942, 0.77258285]])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.random.randn(3,2) # parameter is not shape as an object but content of shape\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ordered numbers (linspace and arange)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create 10 elements between 0 and 1, i element [0,1]:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 0.11111111, 0.22222222, 0.33333333, 0.44444444,\n", " 0.55555556, 0.66666667, 0.77777778, 0.88888889, 1. ])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar = np.linspace(0,1,10)\n", "ar" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(50,)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar = np.linspace(0,1) # default: 50 elements\n", "ar.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create elements between 0 and 1 with offset 0.1, i element [0,1[: " ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar = np.arange(0,1,0.1)\n", "ar" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar = np.arange(10) # default: start at 0 and offset 1\n", "ar" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Combine two arrays" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar = np.arange(10)+np.arange(10)\n", "ar" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Combine array with scalar:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar = np.arange(10)+1\n", "ar" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ordered nd-arrays (meshgrid and mgrid):" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 1, 2, 3, 4],\n", " [0, 1, 2, 3, 4],\n", " [0, 1, 2, 3, 4]])" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.arange(5) # 0,1,2,3,4\n", "y = np.arange(3) # 0,1,2\n", "xv, yv = np.meshgrid(x, y)\n", "xv" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 0, 0, 0, 0],\n", " [1, 1, 1, 1, 1],\n", " [2, 2, 2, 2, 2]])" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "yv" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Compute the Euclidean distance of each pixel from the upper corner: " ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0. , 1. , 2. , 3. , 4. ],\n", " [1. , 1.41421356, 2.23606798, 3.16227766, 4.12310563],\n", " [2. , 2.23606798, 2.82842712, 3.60555128, 4.47213595]])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dist = (xv**2+yv**2)**0.5\n", "dist" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Array indexing:" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1, 2, 3],\n", " [ 4, 5, 6, 7],\n", " [ 8, 9, 10, 11]])" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1D = np.arange(12)\n", "ar = ar1D.reshape((3,4)) # reindexing (not copying) of the matrix \n", "ar" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-1, 1, 2, 3],\n", " [-1, 5, 6, 7],\n", " [-1, 9, 10, 11]])" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar[:,0] = -1\n", "ar" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "! The 2D matrix is just a \"view\" of the 1D array !" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([-1, 1, 2, 3, -1, 5, 6, 7, -1, 9, 10, 11])" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1D" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "if you want to copy the matrix you must use the copy() function:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "flat copy:" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5 1 2 3 4]\n", "[5 1 2 3 4]\n" ] } ], "source": [ "ar1 = np.arange(5)\n", "ar2 = ar1\n", "ar2[0] = 5\n", "print(ar1)\n", "print(ar2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "deep copy using copy() - function" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0 1 2 3 4]\n", "[5 1 2 3 4]\n" ] } ], "source": [ "ar1 = np.arange(5)\n", "ar2 = ar1.copy()\n", "ar2[0] = 5\n", "print(ar1)\n", "print(ar2)" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-2, -2, -2, -2],\n", " [-2, -2, -2, -2],\n", " [-2, -2, -2, -2]])" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar[:] = -2\n", "ar" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0, 1, 2, 3],\n", " [-1, -1, 6, 7],\n", " [ 8, 9, 10, 11]])" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1D = np.arange(12)\n", "ar = ar1D.reshape((3,4)) \n", "ar[1,0:2] = -1\n", "ar" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0, -3, -3, -3],\n", " [-1, -3, -3, -3],\n", " [ 8, -3, -3, -3]])" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar[:,1:] = -3\n", "ar" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## more about reshape" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0, -3],\n", " [-3, -3],\n", " [-1, -3],\n", " [-3, -3],\n", " [ 8, -3],\n", " [-3, -3]])" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar2 =ar.reshape(6,2)\n", "ar2" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0, -3, -3],\n", " [-3, -1, -3],\n", " [-3, -3, 8],\n", " [-3, -3, -3]])" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar2 = ar.reshape(4,-1) # -1 = placeholder for only valid number (here 3)\n", "ar2" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, 2, 3, 1)" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar2 = ar.reshape(2,-1,3,1) # reshape to 4 dimensional array (only one -1 is allowed)\n", "ar2.shape" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(12,)" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar2 = ar.reshape(-1) # most common use of -1\n", "ar2.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Boolean indexing" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1 = np.arange(12)\n", "ar1" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([False, False, False, True, True, True, True, True, True,\n", " True, True, True])" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool1 = ar1>2\n", "bool1" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([False, False, False, True, True, True, True, True, False,\n", " False, False, False])" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bool2 = np.logical_and(ar1>2,ar1<8)\n", "bool2" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([3, 4, 5, 6, 7])" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1[bool2]" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0, 1, 2, -1, -1, -1, -1, -1, 8, 9, 10, 11])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1[bool2] = -1\n", "ar1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## More numpy commands:" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### max, min, maximum, minimum, clip:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scalar1,scalar2 = 4,8\n", "max(scalar1,scalar2) # this is not numpy!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "maximum of an array (np.max):" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "11" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1 = np.arange(12)\n", "np.max(ar1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "pointwise maximum of two lists (np.maximum):" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 10, 11])" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.maximum(ar1,5) # list & scalar" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0])" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar2 = ar1[-1::-1] # from -1 (end) for all with step size -1\n", "ar2" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([11, 10, 9, 8, 7, 6, 6, 7, 8, 9, 10, 11])" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.maximum(ar1,ar2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Clipping:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([2, 2, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8])" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.minimum(np.maximum(ar1,2),8)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([2, 2, 2, 3, 4, 5, 6, 7, 8, 8, 8, 8])" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.clip(ar1,2,8)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Many commands exist in Python for the same thing: Try to be consistent in your code" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121])" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1*ar1" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121])" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1**2" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121])" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.square(ar1)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121])" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.power(ar1,2)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### Other example: Square root" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 1. , 1.41421356, 1.73205081, 2. ,\n", " 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ,\n", " 3.16227766, 3.31662479])" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.sqrt(ar1)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 1. , 1.41421356, 1.73205081, 2. ,\n", " 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ,\n", " 3.16227766, 3.31662479])" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.power(ar1,0.5)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0. , 1. , 1.41421356, 1.73205081, 2. ,\n", " 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ,\n", " 3.16227766, 3.31662479])" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1**0.5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Matrix operations:" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [], "source": [ "ar1 = np.arange(9).reshape((3,3))" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0, 1, 2],\n", " [3, 4, 5],\n", " [6, 7, 8]])" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 0., 0.],\n", " [0., 1., 0.],\n", " [0., 0., 1.]])" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.eye(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pointwise product of two matrices" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0., 0., 0.],\n", " [0., 4., 0.],\n", " [0., 0., 8.]])" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ar1 * np.eye(3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matrix product of two matrices" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0., 1., 2.],\n", " [3., 4., 5.],\n", " [6., 7., 8.]])" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.matmul(ar1,np.eye(3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dot product of two matrices " ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "12.0" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.vdot(ar1,np.eye(3)) # 0*1 + 4*1 + 8*1" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.6" } }, "nbformat": 4, "nbformat_minor": 2 }