Skip to content

Commit c758664

Browse files
committed
Finish section
1 parent 58fbfef commit c758664

File tree

2 files changed

+66
-12
lines changed

2 files changed

+66
-12
lines changed

03-anatomy.rst

+36-9
Original file line numberDiff line numberDiff line change
@@ -333,20 +333,54 @@ copy:
333333
>>> print(Z2.base is None)
334334
True
335335
336-
Note that some numpy functions return a view while some others return a copy:
336+
Note that some numpy functions return a view when possible (e.g. `ravel
337+
<https://docs.scipy.org/doc/numpy/reference/generated/numpy.ravel.html>`_)
338+
while some others always return a copy (e.g. `flatten
339+
<https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.flatten.html#numpy.ndarray.flatten>`_):
337340
338341
.. code:: pycon
339342
340-
>>> Z = np.arange(9).reshape(3,3).copy()
343+
>>> Z = np.zeros((5,5))
341344
>>> Z.ravel().base is Z
342345
True
346+
>>> Z[::2,::2].ravel().base is Z
347+
False
343348
>>> Z.flatten().base is Z
344349
False
345350
346351
347352
Temporary copy
348353
++++++++++++++
349354
355+
Copies can be made explicitly like in the previous section, but the most
356+
general case is the implicit creation of intermediate copies. This is the case
357+
when you are doing some arithmetic with arrays:
358+
359+
.. code:: pycon
360+
361+
>>> X = np.ones(10, dtype=np.int)
362+
>>> Y = np.ones(10, dtype=np.int)
363+
>>> A = 2*X + 2*Y
364+
365+
In the example above, three intermediate arrays have been created. One for
366+
holding the result of `2*X`, one for holding the result of `2*Y` and the last
367+
one for holding the result of `2*X+2*Y`. In this specific case, the arrays are
368+
small enough and this does not really make a difference. However, if your
369+
arrays are big, then you have be careful with such expression and wonder if you
370+
can do it differently. For example, if only the final result matters and you
371+
don't need `X` nor `Y` afterwards, an alternate solution would be:
372+
373+
.. code:: pycon
374+
375+
>>> X = np.ones(10, dtype=np.int)
376+
>>> Y = np.ones(10, dtype=np.int)
377+
>>> np.multiply(X, 2, out=X)
378+
>>> np.multiply(Y, 2, out=Y)
379+
>>> np.add(X, Y, out=X)
380+
381+
Using this alternate solution, no temporary array has been created. Problem is
382+
that there are many other cases where such copies needs to be created and this
383+
impact the performance like demonstrated on the example below:
350384
351385
.. code:: pycon
352386
@@ -362,13 +396,6 @@ Temporary copy
362396
1000 loops, best of 3: 1.57 ms per loop
363397
364398
365-
366-
367-
368-
Regular indexing returns a view
369-
370-
371-
372399
373400
Conclusion
374401
----------

book.html

+30-3
Original file line numberDiff line numberDiff line change
@@ -674,17 +674,45 @@ <h3><a class="toc-backref" href="#id2">Direct and indirect access</a></h3>
674674
</span><span class="keyword"></span><span class="generic prompt">&gt;&gt;&gt; </span><span class="keyword">print</span><span class="punctuation">(</span><span class="name">Z2</span><span class="operator">.</span><span class="name">base</span> <span class="operator word">is</span> <span class="name builtin pseudo">None</span><span class="punctuation">)</span>
675675
<span class="generic output">True</span>
676676
</pre>
677-
<p>Note that some numpy functions return a view while some others return a copy:</p>
677+
<p>Note that some numpy functions return a view when possible (e.g. <a class="reference external" href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.ravel.html">ravel</a>)
678+
while some others always return a copy (e.g. <a class="reference external" href="https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.flatten.html#numpy.ndarray.flatten">flatten</a>):</p>
678679
<pre class="code pycon literal-block">
679-
<span class="name"></span><span class="generic prompt">&gt;&gt;&gt; </span><span class="name">Z</span> <span class="operator">=</span> <span class="name">np</span><span class="operator">.</span><span class="name">arange</span><span class="punctuation">(</span><span class="literal number integer">9</span><span class="punctuation">)</span><span class="operator">.</span><span class="name">reshape</span><span class="punctuation">(</span><span class="literal number integer">3</span><span class="punctuation">,</span><span class="literal number integer">3</span><span class="punctuation">)</span><span class="operator">.</span><span class="name">copy</span><span class="punctuation">()</span>
680+
<span class="name"></span><span class="generic prompt">&gt;&gt;&gt; </span><span class="name">Z</span> <span class="operator">=</span> <span class="name">np</span><span class="operator">.</span><span class="name">zeros</span><span class="punctuation">((</span><span class="literal number integer">5</span><span class="punctuation">,</span><span class="literal number integer">5</span><span class="punctuation">))</span>
680681
<span class="generic prompt">&gt;&gt;&gt; </span><span class="name">Z</span><span class="operator">.</span><span class="name">ravel</span><span class="punctuation">()</span><span class="operator">.</span><span class="name">base</span> <span class="operator word">is</span> <span class="name">Z</span>
681682
<span class="generic output">True
683+
</span><span class="name"></span><span class="generic prompt">&gt;&gt;&gt; </span><span class="name">Z</span><span class="punctuation">[::</span><span class="literal number integer">2</span><span class="punctuation">,::</span><span class="literal number integer">2</span><span class="punctuation">]</span><span class="operator">.</span><span class="name">ravel</span><span class="punctuation">()</span><span class="operator">.</span><span class="name">base</span> <span class="operator word">is</span> <span class="name">Z</span>
684+
<span class="generic output">False
682685
</span><span class="name"></span><span class="generic prompt">&gt;&gt;&gt; </span><span class="name">Z</span><span class="operator">.</span><span class="name">flatten</span><span class="punctuation">()</span><span class="operator">.</span><span class="name">base</span> <span class="operator word">is</span> <span class="name">Z</span>
683686
<span class="generic output">False</span>
684687
</pre>
685688
</div>
686689
<div class="section" id="temporary-copy">
687690
<h3><a class="toc-backref" href="#id2">Temporary copy</a></h3>
691+
<p>Copies can be made explicitly like in the previous section, but the most
692+
general case is the implicit creation of intermediate copies. This is the case
693+
when you are doing some arithmetic with arrays:</p>
694+
<pre class="code pycon literal-block">
695+
<span class="name"></span><span class="generic prompt">&gt;&gt;&gt; </span><span class="name">X</span> <span class="operator">=</span> <span class="name">np</span><span class="operator">.</span><span class="name">ones</span><span class="punctuation">(</span><span class="literal number integer">10</span><span class="punctuation">,</span> <span class="name">dtype</span><span class="operator">=</span><span class="name">np</span><span class="operator">.</span><span class="name">int</span><span class="punctuation">)</span>
696+
<span class="generic prompt">&gt;&gt;&gt; </span><span class="name">Y</span> <span class="operator">=</span> <span class="name">np</span><span class="operator">.</span><span class="name">ones</span><span class="punctuation">(</span><span class="literal number integer">10</span><span class="punctuation">,</span> <span class="name">dtype</span><span class="operator">=</span><span class="name">np</span><span class="operator">.</span><span class="name">int</span><span class="punctuation">)</span>
697+
<span class="generic prompt">&gt;&gt;&gt; </span><span class="name">A</span> <span class="operator">=</span> <span class="literal number integer">2</span><span class="operator">*</span><span class="name">X</span> <span class="operator">+</span> <span class="literal number integer">2</span><span class="operator">*</span><span class="name">Y</span>
698+
</pre>
699+
<p>In the example above, three intermediate arrays have been created. One for
700+
holding the result of <code>2*X</code>, one for holding the result of <code>2*Y</code> and the last
701+
one for holding the result of <code>2*X+2*Y</code>. In this specific case, the arrays are
702+
small enough and this does not really make a difference. However, if your
703+
arrays are big, then you have be careful with such expression and wonder if you
704+
can do it differently. For example, if only the final result matters and you
705+
don't need <code>X</code> nor <code>Y</code> afterwards, an alternate solution would be:</p>
706+
<pre class="code pycon literal-block">
707+
<span class="name"></span><span class="generic prompt">&gt;&gt;&gt; </span><span class="name">X</span> <span class="operator">=</span> <span class="name">np</span><span class="operator">.</span><span class="name">ones</span><span class="punctuation">(</span><span class="literal number integer">10</span><span class="punctuation">,</span> <span class="name">dtype</span><span class="operator">=</span><span class="name">np</span><span class="operator">.</span><span class="name">int</span><span class="punctuation">)</span>
708+
<span class="generic prompt">&gt;&gt;&gt; </span><span class="name">Y</span> <span class="operator">=</span> <span class="name">np</span><span class="operator">.</span><span class="name">ones</span><span class="punctuation">(</span><span class="literal number integer">10</span><span class="punctuation">,</span> <span class="name">dtype</span><span class="operator">=</span><span class="name">np</span><span class="operator">.</span><span class="name">int</span><span class="punctuation">)</span>
709+
<span class="generic prompt">&gt;&gt;&gt; </span><span class="name">np</span><span class="operator">.</span><span class="name">multiply</span><span class="punctuation">(</span><span class="name">X</span><span class="punctuation">,</span> <span class="literal number integer">2</span><span class="punctuation">,</span> <span class="name">out</span><span class="operator">=</span><span class="name">X</span><span class="punctuation">)</span>
710+
<span class="generic prompt">&gt;&gt;&gt; </span><span class="name">np</span><span class="operator">.</span><span class="name">multiply</span><span class="punctuation">(</span><span class="name">Y</span><span class="punctuation">,</span> <span class="literal number integer">2</span><span class="punctuation">,</span> <span class="name">out</span><span class="operator">=</span><span class="name">Y</span><span class="punctuation">)</span>
711+
<span class="generic prompt">&gt;&gt;&gt; </span><span class="name">np</span><span class="operator">.</span><span class="name">add</span><span class="punctuation">(</span><span class="name">X</span><span class="punctuation">,</span> <span class="name">Y</span><span class="punctuation">,</span> <span class="name">out</span><span class="operator">=</span><span class="name">X</span><span class="punctuation">)</span>
712+
</pre>
713+
<p>Using this alternate solution, no temporary array has been created. Problem is
714+
that there are many other cases where such copies needs to be created and this
715+
impact the performance like demonstrated on the example below:</p>
688716
<pre class="code pycon literal-block">
689717
<span class="name"></span><span class="generic prompt">&gt;&gt;&gt; </span><span class="name">X</span> <span class="operator">=</span> <span class="name">np</span><span class="operator">.</span><span class="name">ones</span><span class="punctuation">(</span><span class="literal number integer">1000000000</span><span class="punctuation">,</span> <span class="name">dtype</span><span class="operator">=</span><span class="name">np</span><span class="operator">.</span><span class="name">int</span><span class="punctuation">)</span>
690718
<span class="generic prompt">&gt;&gt;&gt; </span><span class="name">Y</span> <span class="operator">=</span> <span class="name">np</span><span class="operator">.</span><span class="name">ones</span><span class="punctuation">(</span><span class="literal number integer">1000000000</span><span class="punctuation">,</span> <span class="name">dtype</span><span class="operator">=</span><span class="name">np</span><span class="operator">.</span><span class="name">int</span><span class="punctuation">)</span>
@@ -697,7 +725,6 @@ <h3><a class="toc-backref" href="#id2">Temporary copy</a></h3>
697725
</span><span class="name"></span><span class="generic prompt">&gt;&gt;&gt; </span><span class="name">np</span><span class="operator">.</span><span class="name">add</span><span class="punctuation">(</span><span class="name">X</span><span class="punctuation">,</span> <span class="name">Y</span><span class="punctuation">,</span> <span class="name">out</span><span class="operator">=</span><span class="name">X</span><span class="punctuation">),</span> <span class="name">np</span><span class="operator">.</span><span class="name">add</span><span class="punctuation">(</span><span class="name">X</span><span class="punctuation">,</span> <span class="name">Y</span><span class="punctuation">,</span> <span class="name">out</span><span class="operator">=</span><span class="name">X</span><span class="punctuation">),</span>
698726
<span class="generic output">1000 loops, best of 3: 1.57 ms per loop</span>
699727
</pre>
700-
<p>Regular indexing returns a view</p>
701728
</div>
702729
</div>
703730
<div class="section" id="conclusion">

0 commit comments

Comments
 (0)