Skip to content

Commit 7b0704a

Browse files
committed
Started view and copy section
1 parent 36d059f commit 7b0704a

File tree

3 files changed

+273
-214
lines changed

3 files changed

+273
-214
lines changed

03-anatomy.rst

Lines changed: 74 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -277,41 +277,80 @@ cannot be deduced anymore from the dtype and shape only:
277277
Views and copies
278278
----------------
279279
280-
|WIP|
281-
282-
..
283-
.. code:: python
284-
285-
>>> Z = np.zeros((4,4), dtype=np.int64)
286-
>>> Zc = np.array(Z, order="C")
287-
>>> info(Zc)
288-
>>> Zf = np.array(Z, order="F")
289-
>>> info(Zf)
290-
291-
292-
.. code::
293-
:class: output
294-
295-
------------------------------ ------------------------------
296-
Zc Zf
297-
------------------------------ ------------------------------
298-
Interface (item) Interface (item)
299-
shape: (4, 4) shape: (4, 4)
300-
dtype: int64 dtype: int64
301-
size: 16 size: 16
302-
order: ☑ C ☐ Fortran order: ☐ C ☑ Fortran
303-
304-
Memory (byte) Memory (byte)
305-
item size: 8 item size: 8
306-
array size: 128 array size: 128
307-
strides: (32, 8) strides: (8, 32)
308-
309-
Properties Properties
310-
own data: ☑ Yes ☐ No own data: ☑ Yes ☐ No
311-
writeable: ☑ Yes ☐ No writeable: ☑ Yes ☐ No
312-
contiguous: ☑ Yes ☐ No contiguous: ☑ Yes ☐ No
313-
aligned: ☑ Yes ☐ No aligned: ☑ Yes ☐ No
314-
------------------------------ ------------------------------
280+
Views and copies are important concepts for the optimization of your numerical
281+
computations. Even if we've already manipulated them in the previous section,
282+
the whole story is a bit more complex.
283+
284+
Direct and indirect access
285+
++++++++++++++++++++++++++
286+
287+
First, we have to distinguish between `indexing
288+
<https://docs.scipy.org/doc/numpy/user/basics.indexing.html#>`_ and `fancy
289+
indexing <https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#advanced-indexing>`_. The first will always return a view while the second will return a
290+
copy. This difference is important because in the first case, modifying the view
291+
modifies the base array while this is not true in the second case:
292+
293+
.. code:: pycon
294+
295+
>>> Z = np.zeros(9)
296+
>>> Z_view = Z[:3]
297+
>>> Z_view[...] = 1
298+
>>> print(Z)
299+
[ 1. 1. 1. 0. 0. 0. 0. 0. 0.]
300+
>>> Z = np.zeros(9)
301+
>>> Z_copy = Z[[0,1,2]]
302+
>>> Z_copy[...] = 1
303+
>>> print(Z)
304+
[ 0. 0. 0. 0. 0. 0. 0. 0. 0.]
305+
306+
Thus, if you need fancy indexing, it's better to keep a copy of you fancy index
307+
and to work with it:
308+
309+
.. code:: pycon
310+
311+
>>> Z = np.zeros(9)
312+
>>> index = [0,1,2]
313+
>>> Z[index] = 1
314+
>>> print(Z)
315+
[ 1. 1. 1. 0. 0. 0. 0. 0. 0.]
316+
317+
318+
.. code:: pycon
319+
320+
>>> Z = np.random.uniform(0,1,(5,,5))
321+
>>> Z1 = Z[:3,:]
322+
>>> Z2 = Z[[0,1,2], :]
323+
>>> print(np.allclose(Z1,Z2))
324+
True
325+
>>> print(Z1.base is Z)
326+
True
327+
>>> print(Z2.base is Z)
328+
False
329+
330+
331+
Temporary copy
332+
++++++++++++++
333+
334+
335+
.. code:: pycon
336+
337+
>>> X = np.ones(1000000000, dtype=np.int)
338+
>>> Y = np.ones(1000000000, dtype=np.int)
339+
>>> timeit("X = X + 2.0*Y", globals())
340+
100 loops, best of 3: 3.61 ms per loop
341+
>>> timeit("X = X + 2*Y", globals())
342+
100 loops, best of 3: 3.47 ms per loop
343+
>>> timeit("X += 2*Y", globals())
344+
100 loops, best of 3: 2.79 ms per loop
345+
>>> np.add(X, Y, out=X), np.add(X, Y, out=X),
346+
1000 loops, best of 3: 1.57 ms per loop
347+
348+
349+
350+
351+
352+
Regular indexing returns a view
353+
315354
316355
317356

0 commit comments

Comments
 (0)