{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to Numpy\n", "\n", "NumPy is THE fundamental library for scientific calculation in python. You can play with this library to do deeplearning but NumPy is not the best choice... Nevertheless, most scientific libs rely on NumPy conventions and APIs so it is important to have some knowledges about it. If you are familiar with NumPy, you can skip this section and go to the section _Introduction to Tensorflow_\n", "\n", "## The `ndarray` class\n", "\n", "To use NumPy you should import it with the following command" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now you can use Numpy with the shortcut `np`.\n", "\n", "The fundamental class of NumPy is `ndarray`. It represents table of items, with the following constraints:\n", "\n", "* It's _multidimensional_ (1d, 2d, 3d, ..., nd),\n", "* It's _homogeneous_, that is, all items inside the table should belong to the same type.\n", "\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1. , 2. , 3. ],\n", " [3. , 4. , 0.5]])" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Ndarray instanciation from known values\n", "a = np.array([[1., 2., 3.], [3., 4., .5]])\n", "a" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "numpy.ndarray" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Type of a\n", "type(a)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 'Rank' as mention in NumPy doc or number of dimensions\n", "a.ndim" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(2, 3)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Shape of the ndarray\n", "a.shape" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Total number of items\n", "a.size" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dtype('float64')" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Item type\n", "a.dtype" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Actual data of the table\n", "a.data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creation of a `ndarray`\n", "\n", "The basic constructors of `ndarray`are :\n", "\n", "* `numpy.array(object, dtype=None, copy=True, order=’K’, subok=False, ndmin=0)`\n", "Create an array from known values\n", "* `numpy.zeros(shape, dtype=float, order=’C)`\n", "Create an array full of zeros\n", "* `numpy.ones(shape, dtype=None, order=’C’)`\n", "Create an array full of ones\n", "\n", "`dtype` determines the type of each element, `order` indicates how elements are organized into `data` .\n", "\n", "**Take Care !** `dtype` is determined at instanciation and can not be changed after.\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1. , 2. , 3. ],\n", " [3. , 4. , 0.5]])" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.array([[1., 2., 3.], [3., 4., .5]])" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0., 0., 0.],\n", " [0., 0., 0.],\n", " [0., 0., 0.],\n", " [0., 0., 0.],\n", " [0., 0., 0.]])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.zeros((5, 3))" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "array([[[1, 1, 1],\n", " [1, 1, 1]],\n", "\n", " [[1, 1, 1],\n", " [1, 1, 1]]])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.ones((2, 2, 3), dtype='int')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some other useful methods are :\n", "\n", "* `numpy.arange([start, ]stop, [step, ]dtype=None)`\n", "* `numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)`\n", "* `numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)`\n", "* `numpy.eye(N, M=None, k=0, dtype=float)`\n", "* `numpy.random.randn(d0, d1, ..., dn)`\n", "\n", "More creation routines are available [here](https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html)." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([5, 6, 7, 8, 9])" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.arange(5, 10, 1)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 2, 4, 6, 8])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.arange(0, 10, 2)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0. , 0.52631579, 1.05263158, 1.57894737, 2.10526316,\n", " 2.63157895, 3.15789474, 3.68421053, 4.21052632, 4.73684211,\n", " 5.26315789, 5.78947368, 6.31578947, 6.84210526, 7.36842105,\n", " 7.89473684, 8.42105263, 8.94736842, 9.47368421, 10. ])" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.linspace(0, 10, 20)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1.00000000e+01, 2.97635144e+01, 8.85866790e+01, 2.63665090e+02,\n", " 7.84759970e+02, 2.33572147e+03, 6.95192796e+03, 2.06913808e+04,\n", " 6.15848211e+04, 1.83298071e+05, 5.45559478e+05, 1.62377674e+06,\n", " 4.83293024e+06, 1.43844989e+07, 4.28133240e+07, 1.27427499e+08,\n", " 3.79269019e+08, 1.12883789e+09, 3.35981829e+09, 1.00000000e+10])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.logspace(1, 10, 20)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 0., 0.],\n", " [0., 1., 0.],\n", " [0., 0., 1.]])" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.eye(3)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1., 0., 0., 0.],\n", " [0., 1., 0., 0.],\n", " [0., 0., 1., 0.]])" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.eye(3, 4)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-0.0435123 , 2.12342016, -0.3517692 , -0.37803699],\n", " [-0.6603126 , 1.47938205, 0.74353841, 0.01077219],\n", " [ 1.25235323, 0.17773648, -1.34153894, 0.83950519]])" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.random.randn(3, 4)\n", "# !!! shape is given dimension by dimension as arguments not in one tuple" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Indexation / Slicing\n", "\n", "### Monodimensional indexation\n", "\n", "Indexing and slicing are done with the operator `[]` as for list." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0.38561388, 0.1312874 , -1.77371446, 0.20922443, 1.99598316,\n", " -1.10727819, 1.07983388, 1.12979408, 0.8988875 , -2.33405206])" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.random.randn(10)\n", "a" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.3856138828937419" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# First item\n", "a[0]" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-2.334052056277316" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Last item\n", "a[-1]" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([-1.77371446, 0.20922443, 1.99598316])" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# From item 2 to item 5 (excluded !)\n", "a[2:5]" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0.38561388, 0.1312874 , -1.77371446])" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Eliptic formulation\n", "# 3 first items\n", "a[:3]" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0.20922443, 1.99598316, -1.10727819, 1.07983388, 1.12979408,\n", " 0.8988875 , -2.33405206])" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Starting from the 4th item\n", "a[3:]" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0.38561388, 0.1312874 , -1.77371446, 0.20922443, 1.99598316,\n", " -1.10727819, 1.07983388, 1.12979408, 0.8988875 , -2.33405206])" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# All items\n", "a[:]" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([-1.77371446, 1.99598316, 1.07983388])" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# With a step\n", "a[2:8:2]" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([-2.33405206, 0.8988875 , 1.12979408, 1.07983388, -1.10727819,\n", " 1.99598316, 0.20922443, -1.77371446, 0.1312874 , 0.38561388])" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Reverse\n", "a[::-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Multidimensional indexation" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[[-1.45499873, 0.60968565, 0.96500901, -1.56774256,\n", " -0.5823915 ],\n", " [ 0.94823332, 0.24173161, -0.24645756, 0.26872042,\n", " 1.67306428],\n", " [ 0.04360488, 0.55531735, -1.24950238, -0.25182346,\n", " -0.88974734],\n", " [ 0.11518298, -1.43411316, 1.50391982, -0.56323472,\n", " -0.48075885]],\n", "\n", " [[ 0.20507796, -0.42739154, 0.08603242, -1.20745744,\n", " 0.01711814],\n", " [-1.29099347, 0.02268427, 1.05075633, -0.44586989,\n", " 1.45876102],\n", " [-0.19055536, 1.36780152, 0.0881775 , 1.29125986,\n", " -0.18357063],\n", " [ 2.23198325, 0.5520259 , 0.7517003 , -2.42938987,\n", " 0.20634189]],\n", "\n", " [[-2.73825075, 1.02797841, -1.7735629 , 0.66537866,\n", " -0.39395895],\n", " [-1.69521282, -0.19509658, 0.68660841, -0.15368767,\n", " -0.89636285],\n", " [ 1.39049358, -0.65005792, -0.36788816, -0.34044015,\n", " -0.31725071],\n", " [-0.18828673, -0.18759523, -0.87914565, -1.65259218,\n", " -0.92335552]]])" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = np.random.randn(3, 4, 5)\n", "b" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-1.4549987250944822" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# First item on each axis\n", "b[0, 0, 0]" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-0.24645756, 0.26872042, 1.67306428],\n", " [ 1.05075633, -0.44586989, 1.45876102],\n", " [ 0.68660841, -0.15368767, -0.89636285]])" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# With an interval and ann elipse\n", "b[:, 1, 2:5]" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-2.73825075, 1.02797841, -1.7735629 , 0.66537866, -0.39395895],\n", " [-1.69521282, -0.19509658, 0.68660841, -0.15368767, -0.89636285],\n", " [ 1.39049358, -0.65005792, -0.36788816, -0.34044015, -0.31725071],\n", " [-0.18828673, -0.18759523, -0.87914565, -1.65259218, -0.92335552]])" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# a[2] is equivalent to a[2,:,:]\n", "b[2]" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[[[-0.35956823, 0.65123647, -0.79485964],\n", " [ 1.38711688, -0.72095591, -0.31142876]],\n", "\n", " [[ 0.11768983, -0.60527716, -1.64752649],\n", " [ 0.92145919, -0.6481817 , -0.85347846]]],\n", "\n", "\n", " [[[ 0.30409495, -0.0871556 , -1.46601627],\n", " [ 1.28863748, 0.18944056, -0.79280346]],\n", "\n", " [[ 0.06680389, 1.32417265, 0.11993329],\n", " [-0.07648969, 0.95043854, 1.4697187 ]]]])" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Multiple elipses : c[1,...,2] is equivalent to c[1,:,:,2] on 4-D array\n", "c = np.random.randn(2, 2, 2, 3)\n", "c" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-1.46601627, -0.79280346],\n", " [ 0.11993329, 1.4697187 ]])" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c[1, ..., 2]" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-1.46601627, -0.79280346],\n", " [ 0.11993329, 1.4697187 ]])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c[1, :, :, 2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " ### Indexation implies cut in dimension ! (Warning for Matlab users)\n", " \n", " Important for matrix operation (multiplication...)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.97215472, -0.78910336, 0.44128341],\n", " [ 0.18547472, -1.22244959, 0.9214553 ],\n", " [ 0.17964464, 1.33731686, 0.13527983],\n", " [-1.13387243, 0.64657783, -0.0359727 ]])" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.random.randn(4, 3)\n", "a" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0.97215472, 0.18547472, 0.17964464, -1.13387243])" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = a[:, 0]\n", "b" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(4,)" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# b has shape (4,) not (4,1)\n", "b.shape" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0.97215472, -0.78910336, 0.44128341])" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c = a[0, :]\n", "c" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(3,)" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# c has shape (3,) not (1,3)\n", "c.shape" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.97215472, -0.78910336, 0.44128341]])" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Meanwhile using slice and not index preserves dimension\n", "d = a[0:1, :]\n", "d" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 3)" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Assignation\n", "\n", "Assignation is performed by the operator `=`. Item or a sub-array can be targeted.\n" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[1, 2, 3],\n", " [4, 5, 6]])" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.array([[1, 2, 3], [4, 5, 6]], dtype=int)\n", "a" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[10, 2, 3],\n", " [ 4, 5, 6]])" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[0, 0] = 10\n", "a" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[10, 1, 1],\n", " [ 4, 1, 1]])" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a[0:2, 1:3] = np.ones((2, 2))\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Take Care !** `dtype` is determined at instanciation and can not be changed after." ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[10, 1, 1],\n", " [ 1, 1, 1]])" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1.75 will be downcast before assignation\n", "a[1, 0] = 1.75\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Resize operation\n", "\n", "Arrays can be reshaped by the `resize` method. That's an in-place operation:\n" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[10, 1],\n", " [ 1, 1],\n", " [ 1, 1]])" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.resize((3, 2))\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## References, view and copy\n", "\n", "\n", "If `a` and `b` reference the same `ndarray`, all operation on `a`also applied to `b`. They share both data and metadata. \n", "\n", "If `c` is a view of `a`, they share the same data but not the metadata. For example shapes can be modified separately. But if we change the first element of `c`, the first element of `a` is also changed.\n", "\n", "If `d` is a copy of `a`, all data and metadata are separated.\n" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-0.27481389, 0.59862034, 0.01464082],\n", " [ 2.22461135, -0.16125853, -0.04968828],\n", " [-0.02298794, -0.41436418, -0.92506087],\n", " [ 1.08093282, -0.66716209, -0.62792629]])" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.random.randn(4, 3)\n", "a" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1. , 0.59862034, 0.01464082],\n", " [ 2.22461135, -0.16125853, -0.04968828],\n", " [-0.02298794, -0.41436418, -0.92506087],\n", " [ 1.08093282, -0.66716209, -0.62792629]])" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# b is a reference to a\n", "b = a\n", "b[0, 0] = 1\n", "a" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1. , 0.59862034, 0.01464082, 2.22461135],\n", " [-0.16125853, -0.04968828, -0.02298794, -0.41436418],\n", " [-0.92506087, 1.08093282, -0.66716209, -0.62792629]])" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# c is a view of a\n", "c = a.view()\n", "c.resize(3, 4)\n", "c" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1. , 0.59862034, 0.01464082],\n", " [ 2.22461135, -0.16125853, -0.04968828],\n", " [-0.02298794, -0.41436418, -0.92506087],\n", " [ 1.08093282, -0.66716209, -0.62792629]])" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Shape of a is not affected\n", "a" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1. , 0.59862034, 0.01464082],\n", " [ 2.22461135, -0.16125853, -0.04968828],\n", " [-0.02298794, -0.41436418, -0.92506087],\n", " [ 1.08093282, -0.66716209, 0. ]])" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# But if we modify the last element of c, the last element of a is changed\n", "c[2, 3] = 0\n", "a" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1. , 0.59862034, 0.01464082],\n", " [ 2.22461135, -0.16125853, -0.04968828],\n", " [-0.02298794, -0.41436418, -0.92506087],\n", " [ 1.08093282, -0.66716209, 0. ]])" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# d is a copy of a\n", "d = a.copy()\n", "d" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 3. , 0.59862034, 0.01464082],\n", " [ 2.22461135, -0.16125853, -0.04968828],\n", " [-0.02298794, -0.41436418, -0.92506087],\n", " [ 1.08093282, -0.66716209, 0. ]])" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d[0, 0] = 3\n", "d" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1. , 0.59862034, 0.01464082],\n", " [ 2.22461135, -0.16125853, -0.04968828],\n", " [-0.02298794, -0.41436418, -0.92506087],\n", " [ 1.08093282, -0.66716209, 0. ]])" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# a was not modified by the assigniation on d\n", "a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Shape manipulation\n", "\n", "* `ndarray.resize(new shape, refcheck=True)`\n", "Resize in-place\n", "* `ndarray.reshape(shape, order=’C’)`\n", "Return a view with a new shape\n", "* `ndarray.ravel(order=’C’)`\n", "Return a flatten view\n", "* `ndarray.flatten(order=’C’)`\n", "Return a flatten copy\n", "* `numpy.concatenate((a1, a2, ...), axis=0)`\n", "Return a concatenation of arrays along an existing axis\n", "* `numpy.stack((a1, a2, ...), axis=0)`\n", "Return a stack of arrays along a new axis\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Operations\n", "\n", "Simple operations +, -, \\*, \\*\\*, / operate item by item" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.92405372, 0.09652336, -0.31998292],\n", " [ 0.18227558, -0.64323192, 2.00728865],\n", " [ 0.38859642, -0.15633407, 0.42904298],\n", " [ 0.59067084, -0.46896047, -1.29174562]])" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.random.randn(4, 3)\n", "a" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.30297353, -0.99762754, -0.73577338],\n", " [ 0.0567732 , -0.90825298, -2.00021683],\n", " [-0.31508253, 0.31644956, 1.93990276],\n", " [-1.11142293, 0.23842539, 0.30297604]])" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = np.random.randn(4, 3)\n", "b" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 1.22702725, -0.90110419, -1.0557563 ],\n", " [ 0.23904878, -1.5514849 , 0.00707182],\n", " [ 0.0735139 , 0.1601155 , 2.36894574],\n", " [-0.52075209, -0.23053509, -0.98876958]])" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a + b" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.27996382, -0.09629436, 0.23543491],\n", " [ 0.01034837, 0.58421731, -4.01501255],\n", " [-0.12243994, -0.04947185, 0.83230166],\n", " [-0.65648512, -0.11181208, -0.39136797]])" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a * b" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0.85387528, 0.00931676, 0.10238907],\n", " [0.03322439, 0.4137473 , 4.02920773],\n", " [0.15100718, 0.02444034, 0.18407788],\n", " [0.34889205, 0.21992392, 1.66860674]])" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a ** 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Arrays can be viewed as set where we can get min/max of all items." ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-1.2917456189907488" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.min()" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.007288651529005" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.max()" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "11" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Position of the min in the flatten view of the array\n", "a.argmin()" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "5" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.argmax()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you want to compute an extremum along a particular axis, you should precise `axis` in argument. As indexing, this reduce the dimension of the array. If you want to keep the same number of dimension, you should set the `keepdims` argument to `True`." ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([-0.31998292, -0.64323192, -0.15633407, -1.29174562])" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.min(axis=1)" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-0.31998292],\n", " [-0.64323192],\n", " [-0.15633407],\n", " [-1.29174562]])" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a.min(axis=1, keepdims=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Broadcasting\n", "\n", "Broadcasting is a mechanism to automatically tile arrays of incompatible dimensions before an operation.\n", "This is a powerfull mechanism (you don't have to use `repmat` as in Matlab) but it can hide dimensionality errors." ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(1, 4)" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.array([[1, 2, 3, 4]])\n", "a.shape" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(3, 1)" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = np.array([[5], [6], [7]])\n", "b.shape" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 6, 7, 8, 9],\n", " [ 7, 8, 9, 10],\n", " [ 8, 9, 10, 11]])" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# a and b are tiled, line by line for a, column by column for b, to enable the add operation\n", "c = a+b\n", "c" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(3, 4)" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Linear Algebra\n", "### 1D arrays\n", "\n", "* `numpy.inner(a, b)`\n", "Return the inner/scalar product of 2 vectors\n", "* `numpy.outer(a, b)`\n", "Return the outer product of 2 vectors" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 2, 3, 4])" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.array([1, 2, 3, 4])\n", "a" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([5, 6, 7, 8])" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "b = np.array([5, 6, 7, 8])\n", "b" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "70" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.inner(a, b)" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 5, 6, 7, 8],\n", " [10, 12, 14, 16],\n", " [15, 18, 21, 24],\n", " [20, 24, 28, 32]])" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.outer(a, b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2D arrays\n", "\n", "* `a.T` is the transposition of `a`\n", "* `numpy.dot(a, b)` return the matrix product between a and b." ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[ 0.35970533, 0.82933675, -0.28593392],\n", " [ 0.11714446, 0.48988585, -0.21440799],\n", " [ 0.37182741, -0.94559446, 0.80436999],\n", " [ 0.04891257, 1.02279121, 0.33140726],\n", " [ 0.48148513, -1.26135326, 0.7512605 ]])" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.random.randn(3, 5)\n", "a.T" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-1.93791225, -0.80052914],\n", " [-1.0058203 , 1.46348968],\n", " [-1.82776987, -1.80662118]])" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = np.random.randn(3, 5)\n", "b = np.random.randn(5, 2)\n", "np.dot(a, b)" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-1.93791225, -0.80052914],\n", " [-1.0058203 , 1.46348968],\n", " [-1.82776987, -1.80662118]])" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Equivalent notation\n", "a.dot(b)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[-1.93791225, -0.80052914],\n", " [-1.0058203 , 1.46348968],\n", " [-1.82776987, -1.80662118]])" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Since python 3.5, the @ symbol can be used for matrix multiplication\n", "a @ b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Saving and loading data\n", "\n", "### Input\n", "\n", "* `numpy.load(file, mmap_mode=None, allow_pickle=True, fix_imports=True, encoding='ASCII')`\n", "\n", "load a `npy` or `npz` file,\n", "* `numpy.loadtxt(fname, dtype=, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0)`\n", "\n", "load a `txt` file.\n", "\n", "### Output\n", "\n", "* `numpy.save(file, arr, allow_pickle=True, fix_imports=True)`\n", "\n", "save ONE array into a `npy` file,\n", "\n", "* `numpy.savez(file, *args, **kwds)`\n", "\n", "save many arrays into an `npz` file,\n", "\n", "* `numpy.savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\\n', header='', footer='', comments='# ')`\n", "\n", "save ONE array into a `txt` file,\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Your turn\n", "\n", "Try to answer each following questions by a small snippet of code.\n", "\n", "1. How to reverse a vector (1d array) ?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2. How to keep dimension consistency when slicing a matrix (2d array) ?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "3. How to create a (5,5) array with random values and find the extrema values ?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "4. With the help of broadcasting, how to produce a matrix A where A\\[i,j\\] = 2i + j ? (no for loop allowed)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "5. A is a (4,4) int array, I want to change the last element of A to 1.5 without loosing any information. How can I do it ?" ] } ], "metadata": { "celltoolbar": "Tags", "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.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }