{
"cells": [
{
"cell_type": "markdown",
"id": "850660a6",
"metadata": {},
"source": [
"# Up and Running with Python3\n",
"\n",
"In this notebook we cover `numpy`, very widely used scientific python applications, it is so popular that most of other scientific applications are either built on top of `numpy` or at least support its data types. We cover the basics:\n",
"* [Introduction](#intro)\n",
"* [Data types](#datatype)\n",
"* [Array indexing, reshaping, slicing, masking](#array)\n",
"* [Saving array data](#save)\n",
"* [Linear algebra](#la)\n",
"* [Random numbers](#random)\n",
"* [Conclusion](#conclusion)\n",
"\n",
"This notebook is based on [tutorial](https://github.com/marcodeltutto/Python-Tutorial-SBN-Workshop) by Marco Del Tutto for an introductory workshop.\n",
"\n",
"\n",
"## NumPy: Getting Started\n",
"\n",
"NumPy is a fundamental package for scientific computing with Python. \n",
"Is a Python library adding support for multi-dimensional arrays and matrices, as well as many useful mathematical functions to operate on these arrays.\n",
"\n",
"
"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "4b98c509",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.21.1\n"
]
}
],
"source": [
"import numpy as np\n",
"print(np.__version__)"
]
},
{
"cell_type": "markdown",
"id": "6e744c89",
"metadata": {},
"source": [
"In the previous notebook, we saw how to construct lists. Now, we will start from lists, and see how we can construct numpy arrays from them."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "f1acea43",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[5.1100e-01 1.0566e+02 1.7800e+03]\n"
]
}
],
"source": [
"masses_list = [0.511, 105.66, 1.78e3]\n",
"masses_array = np.array(masses_list)\n",
"print(masses_array)"
]
},
{
"cell_type": "markdown",
"id": "dcf9053a",
"metadata": {},
"source": [
"Multiply every element by a number:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "806f7702",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[5.1100e-04 1.0566e-01 1.7800e+00]\n"
]
}
],
"source": [
"masses_array_gev = masses_array * 1e-3\n",
"print(masses_array_gev)"
]
},
{
"cell_type": "markdown",
"id": "fe369ad8",
"metadata": {},
"source": [
"To get the size of the array, you can use the `len()` function, or the `.size` attribute.\n",
"\n",
"You can get the shape of the object by using the `.shape` attribute"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "cfc2fde0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"len is 3\n",
"size is 3\n",
"shape is (3,)\n"
]
}
],
"source": [
"# EXCERCISE: Check that len and size give the same result. What does shape return?\n",
"print('len is ', len(masses_array))\n",
"print('size is ', masses_array.size)\n",
"print('shape is ', masses_array.shape)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "77ea27e2",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0., 0., 0., 0.],\n",
" [0., 0., 0., 0.],\n",
" [0., 0., 0., 0.],\n",
" [0., 0., 0., 0.],\n",
" [0., 0., 0., 0.]])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# EXCERCISE: Try np.linspace, np.zeros, np.ones\n",
"np.linspace(5, 15, 9)\n",
"np.zeros(9)\n",
"np.ones(9)\n",
"np.zeros((5, 4))"
]
},
{
"cell_type": "markdown",
"id": "9ec8a0ad",
"metadata": {},
"source": [
"\n",
"## NumPy DataTypes\n",
"\n",
"Up until this point, we have been using the default datatypes that NumPy selects for arrays. In the cases for arange and linspace, the default types are integers. \n",
"\n",
"In the case of zeros and ones, the default type is floating point. Each of these functions has a `dtype` parameter. For example, we can look here and we see linspace has a `dtype` parameter and its default value is set to `None`. You can use this parameter to determine the datatype for each element in an array. Remember that each element must have the same datatype. \n",
"\n",
"At this [link](https://docs.scipy.org/doc/numpy/user/basics.types.html) you can find all the NumPy datatypes.\n",
"\n",
"In the previous examples, we saw that the `ones` function and the `zeros` function return arrays that contain floating point values. \n",
"\n",
"You can change this and select the datatype that you want by setting a value for the `dtype` parameter. \n",
"For example you can do `np.ones(9, dtype='int64')`."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "d069d578",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0 0 0 0 0 0 0 0 0 0 0] \n",
"int64\n"
]
}
],
"source": [
"# EXCERCISE: Create an array with zeros that has 11 elements, each of which is a 64-bit integer\n",
"a = np.zeros(11, dtype='int64')\n",
"print(a, type(a))\n",
"print(a.dtype)"
]
},
{
"cell_type": "markdown",
"id": "08e1a4c6",
"metadata": {},
"source": [
"And...there is also the _complex_ data type!\n",
"\n",
"You can specify a complex type in python using `j` as imaginary number, as in `1+2j`."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "71085cab",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[5.1100e-01+0.j 1.0566e+02+0.j 1.7800e+03+0.j 1.0000e+00+2.j]\n"
]
}
],
"source": [
"# EXCERCISE: Try to add an imaginary number to a numpy array and print the array\n",
"masses_list = [0.511, 105.66, 1.78e3]\n",
"masses_list.append(1+2j)\n",
"masses_array = np.array(masses_list)\n",
"print(masses_array)"
]
},
{
"cell_type": "markdown",
"id": "a9c0a86a",
"metadata": {},
"source": [
"\n",
"## Array Indexing, Reshaping, Slicing, Masking"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "4a73e3c5",
"metadata": {},
"outputs": [],
"source": [
"masses_array = np.array([2.2, 4.7, 0.511, 1.28, 96, 105.66, 173e3, 4.18e3, 1.78e3, 0, 0, 91.19e3, 80.39e3, 124.97e3])"
]
},
{
"cell_type": "markdown",
"id": "77ec9068",
"metadata": {},
"source": [
"You can use negatixe index to start counting from the end of the array. \n",
"\n",
"For example, to select the last element:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "f6ba7a5f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"124970.0\n"
]
}
],
"source": [
"print(masses_array[-1])"
]
},
{
"cell_type": "markdown",
"id": "525caed4",
"metadata": {},
"source": [
"Or to select the penultimate element:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "1c57ffbd",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"80390.0\n"
]
}
],
"source": [
"print(masses_array[-2])"
]
},
{
"cell_type": "markdown",
"id": "200aa1b0",
"metadata": {},
"source": [
"### Reshape\n",
"\n",
"The above array `masses_array` is a 1-D array with 14 elements in it. \n",
"Numpy allows to resphape it easily. For example, we can transform it into a 2-D array with 7 columns and 2 rows."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "31942398",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[2.2000e+00 4.7000e+00]\n",
" [5.1100e-01 1.2800e+00]\n",
" [9.6000e+01 1.0566e+02]\n",
" [1.7300e+05 4.1800e+03]\n",
" [1.7800e+03 0.0000e+00]\n",
" [0.0000e+00 9.1190e+04]\n",
" [8.0390e+04 1.2497e+05]]\n"
]
}
],
"source": [
"masses_array_2d = np.reshape(masses_array, (7, 2))\n",
"print(masses_array_2d)"
]
},
{
"cell_type": "markdown",
"id": "bde5028d",
"metadata": {},
"source": [
"`reshape` also exists as an array attribute"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "bd37e722",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[2.2000e+00 4.7000e+00]\n",
" [5.1100e-01 1.2800e+00]\n",
" [9.6000e+01 1.0566e+02]\n",
" [1.7300e+05 4.1800e+03]\n",
" [1.7800e+03 0.0000e+00]\n",
" [0.0000e+00 9.1190e+04]\n",
" [8.0390e+04 1.2497e+05]]\n"
]
}
],
"source": [
"masses_array_2d = masses_array.reshape((7,2))\n",
"print(masses_array_2d)"
]
},
{
"cell_type": "markdown",
"id": "e0b32303",
"metadata": {},
"source": [
"Exercise: try to reshape into `(7,3)`."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "46856982",
"metadata": {},
"outputs": [],
"source": [
"#Exercise: try to reshape into (7,3)"
]
},
{
"cell_type": "markdown",
"id": "2cf7fcbe",
"metadata": {},
"source": [
"`reshape` function allows you to specify one of shape dimension value to be `-1`, which would mean \"go figure out what it should be.\""
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "f09f0f0e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(2, 7)\n"
]
}
],
"source": [
"masses_array_2d = masses_array_2d.reshape((-1,7))\n",
"print(masses_array_2d.shape)"
]
},
{
"cell_type": "markdown",
"id": "59f99684",
"metadata": {},
"source": [
"### Slicing\n",
"\n",
"A basic slice syntax is `i:j:k` where `i` is the starting index, `j` is the stopping index, and `k` is the step:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "1404f8be",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1 3 5]\n"
]
}
],
"source": [
"x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n",
"print(x[1:7:2])"
]
},
{
"cell_type": "markdown",
"id": "3cbf3fa5",
"metadata": {},
"source": [
"Now, if `i` is not given, it defaults to 0.\n",
"\n",
"If `j` is not given, it defaults to the lenght of the array (call it `n`).\n",
"\n",
"If `k` is not given it defaults to 1.\n",
"\n",
"\n",
"**Example** `i = 3`, `j` and `k` defaulted to `n` and 1:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "8cad10a6",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[3 4 5 6 7 8 9]\n"
]
}
],
"source": [
"print(x[3:])"
]
},
{
"cell_type": "markdown",
"id": "8221ef2f",
"metadata": {},
"source": [
"**Example** `i` defaulted to 0, `j = 4` and `k` defaulted and 1:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "2d13c16f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0 1 2 3]\n"
]
}
],
"source": [
"print(x[:4])"
]
},
{
"cell_type": "markdown",
"id": "80cdf3da",
"metadata": {},
"source": [
"**Example** `i` defaulted to 0, `j = 4` and `k = 2`:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "139b9377",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0 2]\n"
]
}
],
"source": [
"print(x[:4:2])"
]
},
{
"cell_type": "markdown",
"id": "1c65d869",
"metadata": {},
"source": [
"### Masking\n",
"Let's start with a numpy array"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "a2b3ca23",
"metadata": {},
"outputs": [],
"source": [
"vector = np.array([26, 14, 1, -28, 8, 7])"
]
},
{
"cell_type": "markdown",
"id": "59bdb6d8",
"metadata": {},
"source": [
"Then, we create a \"mask\". We construct a list with contains True and False values, depending if the elements of `vector` are divisbile or not by 7."
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "a78bf8fe",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[False True False True False True]\n"
]
}
],
"source": [
"mask = 0 == (vector % 7)\n",
"print(mask)"
]
},
{
"cell_type": "markdown",
"id": "72213d8f",
"metadata": {},
"source": [
"Finally, we can applt this mask to our vector in order to select only elements that are divisible by 7:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "7d3dcd4f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[ 14 -28 7]\n"
]
}
],
"source": [
"print(vector[mask])"
]
},
{
"cell_type": "markdown",
"id": "f78aaead",
"metadata": {},
"source": [
"\n",
"## Saving & Reading an array\n",
"\n",
"It's useful to be able to save your array = data! So here's how you can save multiple arrays in a file."
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "1984ebcd",
"metadata": {},
"outputs": [],
"source": [
"np.savez('erase.npz', kazu=masses_array, daniel=masses_array_2d)"
]
},
{
"cell_type": "markdown",
"id": "afa0c1b4",
"metadata": {},
"source": [
"The above command saves `masses_array` and `masses_array_2d` data with keywords \"kazu\" and \"daniel\".\n",
"\n",
"Confirm the file `erase.npz` is created. The choice of this filename is to remind our future-self that this can be removed :)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "566b0a72",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-rw-r--r-- 1 ldomine ki 730 Jun 30 16:24 erase.npz\r\n"
]
}
],
"source": [
"! ls -lht erase.npz "
]
},
{
"cell_type": "markdown",
"id": "fea34ce4",
"metadata": {},
"source": [
"Now let's re-read data from the file."
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "2524dae3",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"numpy.lib.npyio.NpzFile"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data = np.load('erase.npz')\n",
"type(data)"
]
},
{
"cell_type": "markdown",
"id": "3807bdd1",
"metadata": {},
"source": [
"You can access `erase.npz` file contents by the keywords you defined upon saving the data."
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "d675c4d0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"shape of daniel (2, 7)\n",
"contents of kazu\n",
"[2.2000e+00 4.7000e+00 5.1100e-01 1.2800e+00 9.6000e+01 1.0566e+02\n",
" 1.7300e+05 4.1800e+03 1.7800e+03 0.0000e+00 0.0000e+00 9.1190e+04\n",
" 8.0390e+04 1.2497e+05]\n"
]
}
],
"source": [
"print('shape of daniel',data['daniel'].shape)\n",
"print('contents of kazu')\n",
"print(data['kazu'])"
]
},
{
"cell_type": "markdown",
"id": "14e7bcf2",
"metadata": {},
"source": [
"\n",
"## Linear Algebra\n",
"\n",
"The `np.matrix` function returned a matrix from an array like object, or from a string of data. \n",
"\n",
"A matrix is a specialized 2D array that retains its 2D nature through operations. \n",
"\n",
"It has special operators such as asterisk for matrix multiplication, and a double asterisk for matrix power or matrix exponentiation operations.\n",
"\n",
"Let's contruct the a CKM matrix:"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "91c22819",
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'ckm_matarix' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m/tmp/ipykernel_46289/2919251912.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m0.22520\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.97344\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.0412\u001b[0m \u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m [0.00867, 0.0404, 0.999146]])\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mckm_matarix\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mckm_matrix\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNameError\u001b[0m: name 'ckm_matarix' is not defined"
]
}
],
"source": [
"ckm_matrix = np.matrix([[0.97427, 0.22534, 0.00351 ],\n",
" [0.22520, 0.97344, 0.0412 ],\n",
" [0.00867, 0.0404, 0.999146]])\n",
"print(ckm_matarix)\n",
"print(type(ckm_matrix))"
]
},
{
"cell_type": "markdown",
"id": "1be32dfc",
"metadata": {},
"source": [
"Again, we can use the `.shape` attribute to see what is the shape of this matrix:"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "d2d6ddde",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(3, 3)\n"
]
}
],
"source": [
"print(ckm_matrix.shape)"
]
},
{
"cell_type": "markdown",
"id": "c78fd40c",
"metadata": {},
"source": [
"And also `ndim` to see the number of dimensions:"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "c9ad023b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2\n"
]
}
],
"source": [
"print(ckm_matrix.ndim)"
]
},
{
"cell_type": "markdown",
"id": "ba521ced",
"metadata": {},
"source": [
"Let's use the `help` function to see what opetations are available:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "9683bbb6",
"metadata": {},
"outputs": [],
"source": [
"#help(np.matrix)"
]
},
{
"cell_type": "markdown",
"id": "f02590ac",
"metadata": {},
"source": [
"The transpose attribute .T to calculate the transpose of this matrix.\n",
"\n",
"Next we'll use another attribute, .I, to calculate the inverse of this matrix. Notice that the inverse is calculated on my first matrix, and not upon the transform of my first matrix.\n",
"\n",
"For example, is the transpose of the CKM matrix:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "17088912",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"matrix([[0.97427 , 0.2252 , 0.00867 ],\n",
" [0.22534 , 0.97344 , 0.0404 ],\n",
" [0.00351 , 0.0412 , 0.999146]])"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ckm_matrix.T"
]
},
{
"cell_type": "markdown",
"id": "cbf9d9da",
"metadata": {},
"source": [
"Let's check that the CKM matrix is unitary:"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "a18b1938",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 9.99931003e-01 3.78984306e-04 -5.17913575e-03]\n",
" [-1.46579176e-04 9.99999968e-01 8.01956999e-04]\n",
" [ 5.79675730e-03 -2.16445093e-03 1.00003722e+00]]\n"
]
}
],
"source": [
"result = ckm_matrix * ckm_matrix.I.T\n",
"print(result)"
]
},
{
"cell_type": "markdown",
"id": "577a3314",
"metadata": {},
"source": [
"\n",
"## Random numbers\n",
"A random number generator is handy for simulations etc.\n",
"Here's an example of a **flat random number** between 0 to 1."
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "70580ed2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"shape (100000,)\n",
"mean 0.500900215150849 std 0.28911272784081987\n",
"min 3.5732453503523054e-05 max 0.9999933452524224\n"
]
}
],
"source": [
"flat_random = np.random.random(100000)\n",
"print('shape',flat_random.shape)\n",
"print('mean',flat_random.mean(),'std',flat_random.std())\n",
"print('min',flat_random.min(),'max',flat_random.max())"
]
},
{
"cell_type": "markdown",
"id": "4eb4542d",
"metadata": {},
"source": [
"... and there are others, like a normal distribution"
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "44805ac3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"shape (100,)\n",
"mean -0.051172243085185205 std 0.8910350550591932\n",
"min -2.5038000033125143 max 2.158881960944597\n"
]
}
],
"source": [
"flat_random = np.random.randn(100)\n",
"print('shape',flat_random.shape)\n",
"print('mean',flat_random.mean(),'std',flat_random.std())\n",
"print('min',flat_random.min(),'max',flat_random.max())"
]
},
{
"cell_type": "markdown",
"id": "31786f6c",
"metadata": {},
"source": [
"### Random seed\n",
"A reproducible behavior is important for many things including debugging of your code. For a random number generator, this is controlled by what's called _seed_. If you set the random number seed, then the sampled values from a distribution is predictable even though they may appear random. Let's give a shot!"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "30c840af",
"metadata": {},
"outputs": [],
"source": [
"SEED=123\n",
"np.random.seed(SEED)"
]
},
{
"cell_type": "markdown",
"id": "d47f68ec",
"metadata": {},
"source": [
"Now let's sample 3 random values sampled from a normal distribution."
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "66f05e69",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-1.0856306 0.99734545 0.2829785 ]\n"
]
}
],
"source": [
"print(np.random.randn(3))"
]
},
{
"cell_type": "markdown",
"id": "36d96a8d",
"metadata": {},
"source": [
"... and try again."
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "a358a7ad",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-1.50629471 -0.57860025 1.65143654]\n"
]
}
],
"source": [
"print(np.random.randn(3))"
]
},
{
"cell_type": "markdown",
"id": "133b9360",
"metadata": {},
"source": [
"OK, so I don't know what values come out if we try yet another time. However, if we re-set he seed, we can expect the exact same values to be drawn."
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "78134153",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[-1.0856306 0.99734545 0.2829785 ]\n"
]
}
],
"source": [
"SEED=123\n",
"np.random.seed(SEED)\n",
"print(np.random.randn(3))"
]
},
{
"cell_type": "markdown",
"id": "c7502666",
"metadata": {},
"source": [
"_Voila_!\n",
"\n",
"\n",
"\n",
"# Conclusions\n",
"You know, you can also fly with Python. Let's try:"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "639c6343",
"metadata": {},
"outputs": [],
"source": [
"import antigravity"
]
}
],
"metadata": {
"jupytext": {
"cell_metadata_filter": "-all",
"formats": "md:myst",
"text_representation": {
"extension": ".md",
"format_name": "myst",
"format_version": 0.13,
"jupytext_version": "1.10.3"
}
},
"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.8.10"
},
"source_map": [
14,
37,
40,
43,
47,
50,
53,
58,
65,
71,
86,
91,
96,
102,
106,
108,
113,
115,
117,
119,
125,
128,
131,
134,
137,
139,
142,
145,
150,
153,
163,
165,
168,
170,
173,
175,
179,
181,
184,
187,
190,
192,
198,
200,
205,
207,
210,
213,
216,
220,
232,
238,
241,
243,
245,
247,
249,
251,
258,
260,
263,
266,
272,
277,
280,
285,
289,
292,
295,
297,
300,
302,
305,
309,
317
]
},
"nbformat": 4,
"nbformat_minor": 5
}