Skip to content

Commit a2aeb8c

Browse files
committed
Some tweaks to the Advanced Numpy lesson
1 parent 9dca50f commit a2aeb8c

File tree

1 file changed

+34
-18
lines changed

1 file changed

+34
-18
lines changed

content/numpy-advanced.rst

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,26 @@ NumPy copies data are not trivial and it is worth your while to take a closer
136136
look at them. This involves developing an understanding of how NumPy's
137137
:class:`numpy.ndarray` datastructure works behind the scenes.
138138

139+
140+
An example: matrix transpose
141+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142+
Transposing a matrix means that all rows become columns and all columns become
143+
rows. 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::
145+
146+
import numpy as np
147+
rng = np.random.default_rng(seed=0)
148+
a = rng.rand(10_000, 20_000)
149+
print(f'Matrix `a` takes up {a.nbytes / 10**6} MB')
150+
151+
Let's time the :func:`numpy.transpose` function::
152+
153+
%%timeit
154+
b = a.transpose()
155+
156+
It takes mere nanoseconds to transpose 1600 MB of data! How?
157+
158+
139159
The ndarray exposed
140160
~~~~~~~~~~~~~~~~~~~
141161
The first thing you need to know about :class:`numpy.ndarray` is that the
@@ -159,15 +179,19 @@ Exercise 2
159179

160180
.. challenge:: Exercises: Numpy-Advanced-2
161181

162-
Write a function called ``ravel()`` that takes as input:
182+
Write a function called ``ravel()`` that takes the row and column of an
183+
element in a 2D matrix and produces the appropriate index in an 1D array,
184+
where all the rows are concatenated. See the image above to remind yourself
185+
how each row of the 2D matrix ends up in the 1D array.
186+
187+
The function takes these inputs:
163188

164189
- ``row`` The row of the requested element in the matrix as integer index.
165190
- ``col`` The column of the requested element in the matrix as integer index.
166191
- ``n_rows`` The total number of rows of the matrix.
167192
- ``n_cols`` The total number of columns of the matrix.
168193

169-
And produces as output the appropriate index in the 1D array. Use the image above as a
170-
guide. Here are some examples of input and desired output:
194+
Here are some examples of input and desired output:
171195

172196
- ``ravel(2, 3, n_rows=4, n_cols=4)`` → ``11``
173197
- ``ravel(2, 3, n_rows=4, n_cols=8)`` → ``19``
@@ -201,25 +225,15 @@ double-precision floating point numbers. Each one of those bad boys takes up 8
201225
bytes, so all the indices are multiplied by 8 to get to the proper byte in the
202226
memory array. To move to the next column in the matrix, we skip ahead 8 bytes.
203227

204-
205-
An example: matrix transpose
206-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
207-
Transposing a matrix means that all rows become columns and all columns become
208-
rows. All off-diagonal values change places. Let's see how long NumPy's
209-
transpose function takes, by transposing a huge (10 000 ✕ 20 000) matrix::
228+
So now we know the mystery beding the speed of `transpose()`. NumPy can avoid
229+
copying any data by just modifying the ``.strides`` of the array::
210230

211231
import numpy as np
212-
a = rng.rand(10_000, 20_000)
213-
print(f'Matrix `a` takes up {a.nbytes / 10**6} MB')
214232

215-
Let's time the :func:`numpy.transpose` function::
216-
217-
%%timeit
233+
rng = np.random.default_rng(seed=0)
234+
a = rng.rand(10_000, 20_000)
218235
b = a.transpose()
219236

220-
It takes mere nanoseconds to transpose 1600 MB of data! NumPy avoided copying
221-
any data by *only* modifying the ``.strides`` of the existing array in-place::
222-
223237
print(a.strides) # (160000, 8)
224238
print(b.strides) # (8, 160000)
225239

@@ -228,6 +242,7 @@ Another example: reshaping
228242
Modifying the shape of an array through :func:`numpy.reshape` is also
229243
accomplished without any copying of data by modifying the ``.strides``::
230244

245+
rng = np.random.default_rng(seed=0)
231246
a = rng.rand(20_000, 10_000)
232247
print(f'{a.strides=}') # (80000, 8)
233248
b = a.reshape(40_000, 5_000)
@@ -294,7 +309,8 @@ If :func:`numpy.transpose` is fast, and :func:`numpy.reshape` is fast, then
294309
doing them both must be fast too, right?::
295310

296311
# Create a large array
297-
a = np.random.rand(10_000, 20_000)
312+
rng = np.random.default_rng(seed=0)
313+
a = rng.rand(10_000, 20_000)
298314
299315
Measuring the time it takes to first transpose and then reshape::
300316

0 commit comments

Comments
 (0)