Newer
Older
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-33372ef05bccfcb0",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"# Scientific Computing in Python with Numpy \n",
"\n",
"<a href=https://numpy.org/>Numpy</a> (numerical Python) is a library designed for performing scientific computing in Python. \n",
"\n",
"In this notebook, we will introduce numpy arrays, a data structure introduced in numpy for working with vectors and matrices. We will explore how to create them, how to manipulate them, and how to use them for efficient numerical calculations using numpy functions. \n",
"\n",
"**Learning objectives for this notebook:**\n",
"\n",
"* Student is able to create (multidimensional) numpy arrays from a list of numbers\n",
"* Student is able to use indexing and slicing with (multidimensional) numpy arrays\n",
"* Student is able to iterate over a numpy array \n",
"* Student is able to perform mathematical operations on numpy arrays\n",
"* Student is able to use functions for creating arrays (eg. `np.zeros()`, `np.linspace()`, `np.random.random()`\n",
"* Student is able to use numpy functions for vectorized calculations\n",
"* Student is able to demonstrate the speed increase of vectorized calculations using `time()`"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-7d7b639cd03ba916",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"source": [
"## Numpy Arrays\n",
"\n",
"Until now, the variable types we have been working with in Python represent relatively simple data types:\n",
"\n",
"* `int`: integer numbers\n",
"* `float`: floating point numbers\n",
"* `complex`: complex-valued floating point numbers\n",
"* `bool`: boolean \"truth\" values (which can have `True` and `False`)\n",
"* `str`: strings \n",
"* `list`: list of variables\n",
"\n",
"The first four are really actually very simple data types, but actually the last one is more complicated than it looks (see the extra notebook for more details if your interested...). The `list` is a vector like-variable type. However, unlike physical vectors, it cannot be multiplied, subtracted, etc. If you are interested in lists, you can read more about them in the additional material 2.3. \n",
"\n",
"Here, we will introduce a new datatype that is handy for Physics calculations and that comes from the Python software package <a href=https://numpy.org>numpy</a> called **numpy arrays**.\n",
"\n",
"What are numpy arrays? \n",
"\n",
"Numpy arrays are a way to work in Python with not just single numbers, but a whole bunch of numbers. With numpy arrays these numbers can be manipulated just like you do in, for example, linear algebra when one works with vectors:\n",
"\n",
"https://en.wikipedia.org/wiki/Row_and_column_vectors\n",
"\n",
"For example, a (column) vector $\\vec{a}$ with 5 entries might look like this:\n",
"\n",
"$$\n",
"\\vec{a} = \\begin{bmatrix}\n",
"1 \\\\\n",
"2 \\\\\n",
"3 \\\\\n",
"4 \\\\\n",
"5\n",
"\\end{bmatrix}\n",
"$$\n",
"\n",
"In linear algebra you are used to manipulate these vectors, this can be done in a similar way with numpy arrays. We will use numpy arrays extensively in Python as vectors, like above, but also for storing, manipulating, and analyzing datasets (like a column of an excel spreadsheet). \n",
"\n",
"To use numpy arrays, we first need to import the numpy library, which we will do using the shortened name \"np\" (to save typing):"
]
},
{
"cell_type": "code",
Gary Steele
committed
"nbgrader": {
"grade": false,
"grade_id": "cell-4cd897115e9a55da",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
},
"scrolled": true
},
"outputs": [],
"source": [
"import numpy as np"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-2b8a256ccf823e14",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"Now that we have imported numpy, we can use functions in numpy to create a numpy array. A simple way to do this is to use the function `np.array()` to make a numpy array from a comma-separated list of numbers in square brackets:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1,2,3,4,5])\n",
"print(a)"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-cfdb9edf4b2e1707",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"Note that numpy does not make a distinction between row vectors and column vectors: there are just vectors. "
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-aa801acee39c518f",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
"source": [
"### Indexing arrays (and counting from zero)\n",
"\n",
"One useful thing about arrays is that you can access the elements of the array using square brackets:\n",
"\n",
"`a[n]` will give you the n-th element of the array `a`. \n",
"\n",
"This process of extracting a single element from the array is called **indexing**. \n",
"\n",
"Note that here we encounter for the fist time what is know as the python **counting from zero** convention. What is the counting from zero convention? In the example above, we created a array:\n",
"\n",
"```\n",
"a = np.array([1,2,3,4,5])\n",
"```\n",
"\n",
"The first element of `a` is `1`. You might think that if you want to access the first element of `a`, you would use the notation `a[1]`. Right?\n",
"\n",
"Let's try it:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(a[1])"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-992a7aa5df6186e4",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"**WRONG!** Why? Because the makers of Python decided to start counting from zero: the first element of tuple `a` is actually `a[0]`. \n",
"\n",
"(This is a long-standing <a href=https://en.wikipedia.org/wiki/Zero-based_numbering>discussion among computer scientists</a>, and the convention is <a href=https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(array)#Array_dimensions>different</a> in many different languages. There are advantages and disadvantages of both, and even essays written about it...but in any case, Python chose to start arrays at zero.)\n",
"\n",
"This also helps better understand the `range()` function: for example, to loop over all the elements in `a`, I can use this code:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for i in range(len(a)):\n",
" n = a[i]\n",
" print('a[%d] is %d' % (i,n))"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-ab7bf8fa5a2ac10f",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"Here the `len` function returns the length of the array `a`. As we saw before, Python has very smart `for` loops that can automatically iterate over many types of objects, which means we can also print out all the elements of our array like this:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for n in a:\n",
" print(n)"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-e1299e2159378fdb",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"In Python, if you try to index beyond the end of the array, you will get an error: "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"a[5]"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-77aff5e6ccdff810",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
"source": [
"(Remember: indexing starts at zero!)\n",
"\n",
"Python also has a handy feature: negative indices count backwards from the end, and index `-1` corresponds to the last element in the array! "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"a[-1]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"a[-2]"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-8398fd216f6b2f58",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"We can also use indexing to change the values of elements in our array:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(a)\n",
"a[2] = -1\n",
"print(a)"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-3dae75f8494e44f3",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"**Exercise 4.1** Set the first three, and the last two, entries of the following array to zero:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"a = np.array([1,2,3,4,5,6,7,8,9,10,11,32,55,78,22,99,55,33.2,55.77,99,101.3])\n",
"\n",
"#some code to set the first three and last two entries to zero \n",
"\n",
"print(a)"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-3b080cba952a146f",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
"source": [
"### Slicing numpy arrays\n",
"\n",
"Numpy arrays also support a special type of indexing called \"slicing\" that does not just return a single element of an array, but instead returns a whole part of array. \n",
"\n",
"To do this, I put not just a single number inside my square brackets, but instead two numbers, separated by a colon `:`\n",
"\n",
"`a[n:m]` will return a new tuple that consist of all the elements in `a`, starting at element `n` and ending at element `m-1`. \n",
"\n",
"Let's look at a concrete example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"a = np.array(range(10))\n",
"print(a)\n",
"print(a[0:5])"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-70abffff9b88cf27",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
"source": [
"The notation `a[0:5]` has \"sliced\" out the first five elements of the array.\n",
"\n",
"With slicing, you can also leave off either `n` or `m` from the slice: if leave off `n` it will default to `n=0`, and if you leave off `m`, it will default to the end of the array (also the same as `m=-1` in Python indexing):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"print(a[:5])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"print(a[5:])"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-a8b2ffcd10cfc7b1",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"Also handy: you can can have Python slice an array with a \"step\" size that is more than one by adding another `:` and a number after that. Find out its operation using:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"print(a[0:10:2])"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-24b9d17391ceeb7e",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"Fun: you can also use negative steps:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"print(a[-1:-11:-1])"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-6ee08109e60cb51f",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"And finally, unlike indexing, Python is a bit lenient if you slice off the end of an array:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"print(a[0:20])"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-8d1518c5eafa34e8",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"**Exercise 4.2:** Slicing can also be used to *set* multiple values in an array at the same time. Use slicing to set first 10 entries of the array below to zero in one line of code."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"a = np.array(range(20))+1\n",
"print(a)\n",
"some code that sets the first 10 entries to zero\n",
"print(a)"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-9b377accb5c0210c",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
"source": [
"### Mathematical operations on arrays\n",
"\n",
"An advantage of using numpy arrays for scientific computing is that way they behave under mathematical operations. In particular, they very often do exactly what we would want them to do if they were a vector:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([1,2,3,4,5])\n",
"print(2*a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(a+a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"print(a+1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"print(a-a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"print(a/2)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(a**2)"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-2963828a5132a24a",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
"source": [
"What about if I multiply two vectors together? \n",
"\n",
"In mathematics, if I multiply two vectors, what I get depends on if I use the \"dot product\" or the \"outer product\" for my multiplication:\n",
"\n",
"https://en.wikipedia.org/wiki/Row_and_column_vectors#Operations\n",
"\n",
"The \"dot product\" corresponds to multiplying a column vector by a row vector to produce a single number. The \"outer product\" (also called the \"tensor product\") corresponds to multiplying the column vector by the row vector to make a matrix. \n",
"\n",
"**Question:** If I type `a*a`, or more generally `a*b`, does Python use the inner or outer product? \n",
"\n",
"It turns out: it uses **neither!** In Python, the notation `a*a` produces what is commonly called the \"element-wise\" product: specifically,\n",
"\n",
"`a*b = [a[0]*b[0] a[1]*b[1] a[2]*b[2] ...]`\n",
"\n",
"(Mathematically, this has a fancy name called the <a href=https://en.wikipedia.org/wiki/Hadamard_product_(matrices)>Hadamard product</a>, but as you can see, despite the fancy name, it's actually very simple...)\n",
"\n",
"We can see this in action here:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(a*a)"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-713408533e01c84c",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"What if I actually want the dot product or the outer product? For that, Python has functions `np.dot()` and `np.outer()`: "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(np.dot(a,a))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(np.outer(a,a))"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-d29f4ba63452bfee",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"Pretty much all operators work with numpy arrays, even comparison operators, which can sometimes be very handy:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(a)\n",
"print(a>3)"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-8657218bbd2eabbc",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"**Exercise 4.3:** Generate a sequence of the first 20 powers of 2 in a numpy array (starting at $2^0$). \n",
"\n",
"Your output should be an array $[2^0, 2^1, 2^2, 2^3, ...]$. \n",
"\n",
"*(Hint: Start with a numpy array created using an appropriate range function that makes an array [0,1,2,3,...])*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
Gary Steele
committed
"# your code that makes the desired array"
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-809eedfdadcd8b57",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
"source": [
"## Functions for creating numpy arrays\n",
"\n",
"In numpy, there are also several handy functions for automatically creating arrays:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.zeros(10)\n",
"print(a)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.ones(10)\n",
"print(a)"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-a3a728bdca7ae5e3",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
"source": [
"### `np.linspace`\n",
"\n",
"To automatically generate an array with linerly increasing values you can take `np.linspace()`:\n",
"\n",
"https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html\n",
"\n",
"It takes three arguments: the starting number, the ending number, and the number of points.\n",
"\n",
"This is a bit like the `range` function we saw before, but allows you to pick the total number of points, automatically calculating the (non-integer) step size you need:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.linspace(0,20,40)\n",
"print(a)\n",
"print()\n",
"print(\"Length is: \", len(a))\n",
"print(\"Step size is: \", a[1]-a[0])"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-ea30686a4490a44d",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"Note that if we wanted to have a step size of exactly 0.5, we need a total of 41 points:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.linspace(0,20,41)\n",
"print(a)\n",
"print()\n",
"print(\"Length is: \", len(a))\n",
"print(\"Step size is: \", a[1]-a[0])"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-60d973103e7a78a9",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"**Exercise 4.4:** Generate an array that runs from -2 to 1 with 20 points using `linspace`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-7c4a427b963a9b3c",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"### `np.arange()`\n",
"\n",
"If we want to have more control on the exact spacing, we can use the `np.arange()` function. It is like `range()`, asking you for the start, stop, and step size:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.arange(0,20,0.5)\n",
"print(a)\n",
"print()\n",
"print(\"Length is: \", len(a))\n",
"print(\"Step size is: \", a[1]-a[0])"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-5b97dd88408ae9d0",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"Here, we already see a small quirk of `arange`: it will stop once the next point it calculates is `<` (not `<=`) to the stop point. If we want to get a range that stops at `20.0`, we need to make the stop point any number a bit bigger than 20 (but smaller than our step size):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.arange(0,20.00000001,0.5)\n",
"print(a)\n",
"print()\n",
"print(\"Length is: \", len(a))\n",
"print(\"Step size is: \", a[1]-a[0])"
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-ab1a61494f1f5b33",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"For this reason, I do not find myself using `np.arange()` very often, and mostly use `np.linspace()`. There are also several other useful functions, such as <a href=https://docs.scipy.org/doc/numpy/reference/generated/numpy.geomspace.html>np.geomspace()</a>, which produces geometrically spaced points (such that they are evenly spaced on a log scale). "
]
},
{
"cell_type": "markdown",
Gary Steele
committed
"metadata": {
"nbgrader": {
"grade": false,
"grade_id": "cell-3a0d9465353f954b",
"locked": true,
"schema_version": 3,
"solution": false,
"task": false
}
},
"source": [
"**Exercise 4.5:** Generate a numpy array that has a first element with value 60 and last element 50 and takes steps of -0.5 between the values. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [