@@ -10,10 +10,10 @@ Advanced NumPy
1010.. objectives ::
1111
1212 - Understand why NumPy has so many specialized functions for specific operations
13- - Understand the underlying machinery of the Numpy `` ndarray ` ` object
13+ - Understand the underlying machinery of the Numpy :class: ` ~numpy. ndarray ` object
1414 - Understand when and why NumPy makes a copy of the data rather than a view
1515
16- This is intended as a follow-up to the basic NumPy lesson. The indended
16+ This is intended as a follow-up to the :doc: ` basic NumPy lesson < numpy >` . The intended
1717 audience for this advanced lesson is those who have used NumPy before and
1818 now want to learn how to get the most out of this amazing package.
1919
@@ -70,7 +70,9 @@ Exercise 1
7070 Can you beat the C version?
7171
7272 If you are having trouble with this, we recommend completing the
73- :ref: `basic NumPy lession <numpy >` before continuing with this advanced lesson.
73+ :ref: `basic NumPy lession <numpy >` before continuing with this
74+ advanced lesson. If you are taking a live course - don't
75+ worry, watch and learn and explore some during the exercises!
7476
7577.. solution :: Solutions: Numpy-Advanced-2
7678
@@ -118,7 +120,7 @@ use ``%%timeit`` to record how long it takes to execute::
118120 l = np.sqrt(np.sum(a ** 2))
119121 print(l)
120122
121- And here is the version using the specialized BLAS function::
123+ And here is the version using the specialized BLAS function :func: ` ~numpy.linalg.norm ` ::
122124
123125 %%timeit
124126 l = np.linalg.norm(a)
@@ -141,13 +143,14 @@ An example: matrix transpose
141143~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142144Transposing a matrix means that all rows become columns and all columns become
143145rows. All off-diagonal values change places. Let's see how long NumPy's
144- transpose function takes, by transposing a huge (10 000 ✕ 20 000) matrix::
146+ transpose function takes, by transposing a huge (10 000 ✕ 20 000)
147+ :func: `~numpy.random.rand ` matrix::
145148
146149 import numpy as np
147150 a = np.random.rand(10_000, 20_000)
148151 print(f'Matrix `a` takes up {a.nbytes / 10**6} MB')
149152
150- Let's time the :func: ` numpy.transpose ` function ::
153+ Let's time the :meth: ` ~ numpy.ndarray. transpose ` method ::
151154
152155 %%timeit
153156 b = a.transpose()
@@ -216,16 +219,16 @@ of "strides"::
216219 np.zeros((4, 8)).strides # (64, 8)
217220 np.zeros((4, 5, 6, 7, 8)).strides # (13440, 2688, 448, 64, 8)
218221
219- The `` . strides` ` attribute contains for each dimension, the number of *bytes * (not array indexes) we
222+ The :attr: ` ~numpy.ndarray. strides ` attribute contains for each dimension, the number of *bytes * (not array indexes) we
220223have to skip over to get to the next element along that dimension. For example,
221224the result above tells us that to get to the next row in a 4 ✕ 8 matrix, we
222225have to skip ahead 64 bytes. 64? Yes! We have created a matrix consisting of
223226double-precision floating point numbers. Each one of those bad boys takes up 8
224227bytes, so all the indices are multiplied by 8 to get to the proper byte in the
225228memory array. To move to the next column in the matrix, we skip ahead 8 bytes.
226229
227- So now we know the mystery beding the speed of ` transpose() `. NumPy can avoid
228- copying any data by just modifying the `` . strides` ` of the array::
230+ So now we know the mystery behind the speed of :meth: ` ~numpy.ndarray. transpose `. NumPy can avoid
231+ copying any data by just modifying the :attr: ` ~numpy.ndarray. strides ` of the array::
229232
230233 import numpy as np
231234
@@ -238,7 +241,7 @@ copying any data by just modifying the ``.strides`` of the array::
238241Another example: reshaping
239242~~~~~~~~~~~~~~~~~~~~~~~~~~
240243Modifying the shape of an array through :func: `numpy.reshape ` is also
241- accomplished without any copying of data by modifying the `` . strides` `::
244+ accomplished without any copying of data by modifying the :attr: ` ~numpy.ndarray. strides `::
242245
243246 a = np.random.rand(20_000, 10_000)
244247 print(f'{a.strides=}') # (80000, 8)
@@ -253,12 +256,12 @@ Exercises 3
253256
254257.. challenge :: Exercises: Numpy-Advanced-3
255258
256- A little known feature of NumPy is the :data: ` numpy.stride_tricks ` module
257- that allows you to modify the `` . strides` ` attribute directly. Playing
259+ A little known feature of NumPy is the `` numpy.stride_tricks ` ` module
260+ that allows you to modify the :attr: ` ~numpy.ndarray. strides ` attribute directly. Playing
258261 around with this is very educational.
259262
260263 1. Create your own ``transpose() `` function that will transpose a 2D matrix
261- by reversing its `` . shape `` and `` . strides` ` attributes using
264+ by reversing its :attr: ` ~numpy.ndarray. shape ` and :attr: ` ~numpy.ndarray. strides ` attributes using
262265 :func: `numpy.lib.stride_tricks.as_strided `.
263266
264267 2. Create a (5 ✕ 100 000 000 000) array containing on the first row all
@@ -319,7 +322,7 @@ out in memory row-by-row (see image above). The transpose left the data laid
319322out in memory column-by-column. To see why the copying of data was inevitable,
320323look at what happens to this smaller (2 ✕ 3) matrix after transposition and
321324reshaping. You can verify for yourself there is no way to get the final array
322- based on the first array and some clever setting of the `` . strides` `::
325+ based on the first array and some clever setting of the :attr: ` ~numpy.ndarray. strides `::
323326
324327 a = np.array([[1, 2, 3], [4, 5, 6]])
325328
@@ -336,11 +339,11 @@ based on the first array and some clever setting of the ``.strides``::
336339Copy versus view
337340----------------
338341
339- Whenever NumPy constructs a new array by modifying the `` . strides` ` instead of
342+ Whenever NumPy constructs a new array by modifying the :attr: ` ~numpy.ndarray. strides ` instead of
340343copying data, we way it created a "view". This also happens when we select only
341344a portion of an existing matrix. Whenever a view is created, the
342345:class: `numpy.ndarray ` object will have a reference to the original array in
343- its `` . base` ` attribute::
346+ its :attr: ` ~numpy.ndarray. base ` attribute::
344347
345348 a = np.zeros((5, 5))
346349 print(a.base) # None
@@ -357,7 +360,7 @@ it has been derived from::
357360 print(a.__array_interface__['data'])
358361 print(b.__array_interface__['data'])
359362
360- Views are created by virtue of modifying the value of the ` .shape ` attribute
363+ Views are created by virtue of modifying the value of the :attr: ` ~numpy.ndarray .shape ` attribute
361364and, if necessary, apply an offset to the pointer into the memory buffer so it
362365no longer points to the start of the buffer, but somewhere in the middle::
363366
0 commit comments