Skip to content

Commit d435a96

Browse files
authored
Merge pull request #318 from ashwinvis/fixes-numpy-episode
Fixes NumPy episode
2 parents 80042c0 + ec378be commit d435a96

File tree

2 files changed

+42
-12
lines changed

2 files changed

+42
-12
lines changed

content/numpy-advanced.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ Copy versus view
340340
----------------
341341

342342
Whenever NumPy constructs a new array by modifying the :attr:`~numpy.ndarray.strides` instead of
343-
copying data, we way it created a "view". This also happens when we select only
343+
copying data, we create a "view". This also happens when we select only
344344
a portion of an existing matrix. Whenever a view is created, the
345345
:class:`numpy.ndarray` object will have a reference to the original array in
346346
its :attr:`~numpy.ndarray.base` attribute::

content/numpy.rst

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,32 @@ Exercises 2
191191

192192
.. challenge:: Exercises: Numpy-2
193193

194-
- **Matrix multiplication** What is the difference between :data:`numpy.multiply` and :func:`numpy.dot` ? Try it.
195-
- **Axis** What is the difference between :func:`np.sum(axis=1) <numpy.sum>` vs
196-
:func:`np.sum(axis=0) <numpy.sum>` on a two-dimensional array? What if you leave out the axis parameter?
194+
Create the following arrays:
195+
196+
.. code-block:: python
197+
198+
# 1-dimensional arrays
199+
x = np.array([1, 10, 100])
200+
# TODO: similar to `x`, create another 1-dimensional array with shape (3,)
201+
# y = np.array(...)
202+
203+
# 2-dimensional arrays
204+
a = np.array([[1, 2], [3, 4]])
205+
# TODO: similar to `a`, create another 2-dimensional array with shape (2, 2)
206+
# b = np.array(...)
207+
208+
- **Matrix multiplication** What is the difference between :data:`numpy.multiply` and :func:`numpy.dot` ? Try calling these functions
209+
with either ``x, y`` (1D arrays) or ``a, b`` (2D arrays) as input and observe the behaviour.
210+
- **Axis** What is the difference between :func:`np.sum(a, axis=1) <numpy.sum>` vs
211+
:func:`np.sum(a, axis=0) <numpy.sum>` on a two-dimensional array? What if you leave out the axis parameter?
197212

198213

199214
.. solution:: Solutions: Numpy-2
200215

201-
- **Matrix multiplication** ``np.multiply`` does elementwise multiplication on two arrays, while ``np.dot`` enables matrix multiplication.
216+
- **Matrix multiplication** ``np.multiply`` does elementwise multiplication on two arrays. The function ``np.dot`` enables:
217+
- *dot product* and returns a scalar, when both input arrays are 1 dimensional
218+
- *matrix multiplication* and returns back a 2-dimensional array, when both the input arrays are 2 dimensional
219+
However, ``a @ b`` is preferred over ``np.dot(a, b)`` to express matrix multiplication.
202220
- **Axis** ``axis=1`` does the operation (here: ``np.sum``) over each row, while axis=0 does it over each column. If axis is left out, the sum of the full array is given.
203221

204222

@@ -248,18 +266,30 @@ Exercises 3
248266
::
249267

250268
a = np.eye(4)
251-
b = a[:,0]
269+
b = a[:, 0]
252270
b[0] = 5
253271

254-
- **View vs copy** Try out above code. How does ``a`` look like before ``b`` has changed and after? How could it be avoided?
272+
Try out the above code.
273+
274+
- How does ``a`` look like before ``b`` has changed and after?
275+
- How could it be avoided?
255276

256277
.. solution:: Solution: Numpy-3
257278

258-
- **View vs copy** The change in ``b`` has also changed the array ``a``!
259-
This is because ``b`` is merely a view of a part of array ``a``. Both
260-
variables point to the same memory. Hence, if one is changed, the other
261-
one also changes. If you need to keep the original array as is, use
262-
``np.copy(a)``.
279+
**View vs copy**: The change in ``b`` has also changed the array ``a``!
280+
This is because ``b`` is merely a *view* or a *shallow copy* of a part of array ``a``. Both
281+
variables point to the same memory. Hence, if one is changed, the other
282+
one also changes.
283+
284+
In this example, if you need to keep the original array as is, use
285+
:func:`np.copy(a) <numpy.copy>` or ``np.copy(a[:, 0])``
286+
to create a new *deep copy* of the whole or a slice of array respectively,
287+
before updating ``b``.
288+
289+
.. seealso::
290+
291+
NumPy's documentation on :numpy:ref:`quickstart.copies-and-views`
292+
263293

264294

265295
Types of operations

0 commit comments

Comments
 (0)