Skip to content

Commit 1624059

Browse files
committed
DOC: Improved wording and organization
1 parent 7f6e524 commit 1624059

File tree

1 file changed

+62
-58
lines changed

1 file changed

+62
-58
lines changed

doc/source/user/basics.copies.rst

Lines changed: 62 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,65 +4,46 @@
44
Copies and views
55
****************
66

7-
When operating on a NumPy array, we can sometimes improve performance by using
8-
:term:`views <view>` instead of copies of the array. However, when handling
9-
large amounts of important data, it can be risky to directly operate on it and
10-
it could be safer to use copies. Hence, it is important to know the difference
11-
between these two terms to correctly determine when to use which one.
12-
13-
The NumPy array is a :term:`contiguous` block of memory consisting of two parts:
14-
the data buffer with the actual data elements, and the metadata which contains
15-
information about the data buffer. The metadata includes data type, strides
16-
and other important information that helps manipulate the :class:`.ndarray`
17-
easily. See the :ref:`numpy-internals` section for a detailed look.
18-
19-
View or shallow copy
20-
====================
21-
22-
It is possible to access the array differently by just changing the
23-
metadata and without changing the data buffer. This creates a new way of
24-
looking at the data and these new arrays are called views or shallow copies.
25-
The data buffer remains the same so any changes made to a view reflects in the
26-
original copy. A view can be forced through the :meth:`.ndarray.view` method.
27-
28-
29-
Copy or deep copy
30-
=================
7+
When operating on NumPy arrays, it is possible to access the internal data
8+
buffer directly using a :ref:`view <view>` without copying data around. This
9+
ensures good performance but can also cause unwanted problems if the user is
10+
not aware of how this works. Hence, it is important to know the difference
11+
between these two terms and to know which operations return copies and
12+
which return views.
13+
14+
The NumPy array is a data structure consisting of two parts:
15+
the :term:`contiguous` data buffer with the actual data elements and the
16+
metadata that contains information about the data buffer. The metadata
17+
includes data type, strides, and other important information that helps
18+
manipulate the :class:`.ndarray` easily. See the :ref:`numpy-internals`
19+
section for a detailed look.
20+
21+
.. _view:
22+
23+
View
24+
====
25+
26+
It is possible to access the array differently by just changing certain
27+
metadata like :term:`stride` and :term:`dtype` without changing the
28+
data buffer. This creates a new way of looking at the data and these new
29+
arrays are called views. The data buffer remains the same, so any changes made
30+
to a view reflects in the original copy. A view can be forced through the
31+
:meth:`.ndarray.view` method.
32+
33+
Copy
34+
====
3135

3236
When a new array is created by duplicating the data buffer as well as the
33-
metadata, it is called a copy or a deep copy. Changes made to the copy
34-
do not reflect on the original array. Making a copy is slower and memory
35-
consuming but sometimes necessary. A copy can be forced by using
37+
metadata, it is called a copy. Changes made to the copy
38+
do not reflect on the original array. Making a copy is slower and
39+
memory-consuming but sometimes necessary. A copy can be forced by using
3640
:meth:`.ndarray.copy`.
3741

38-
39-
How to tell if the array is a view or a copy
40-
============================================
41-
42-
The :attr:`base <.ndarray.base>` attribute of the ndarray makes it easy
43-
to tell if an array is a view or a copy. The base attribute of a view returns
44-
the original array while for a copy it returns ``None``.
45-
46-
>>> x = np.arange(9)
47-
>>> x
48-
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
49-
>>> y = x.reshape(3, 3)
50-
>>> y
51-
array([[0, 1, 2],
52-
[3, 4, 5],
53-
[6, 7, 8]])
54-
>>> y.base # .reshape() creates a view
55-
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
56-
>>> z = y[[2, 1]]
57-
>>> z
58-
array([[6, 7, 8],
59-
[3, 4, 5]])
60-
>>> z.base is None # advanced indexing creates a copy
61-
True
62-
6342
Indexing operations
6443
===================
6544

45+
.. seealso:: :ref:`basics.indexing`
46+
6647
Views are created when elements can be addressed with offsets and strides
6748
in the original array. Hence, basic indexing always creates views.
6849
For example::
@@ -79,9 +60,10 @@ For example::
7960
>>> y
8061
array([10, 11])
8162

82-
Here ``y`` gets changed when ``x`` is changed because it is a view.
63+
Here, ``y`` gets changed when ``x`` is changed because it is a view.
8364

84-
Advanced indexing, on the other hand, always creates copies. For example::
65+
:ref:`advanced-indexing`, on the other hand, always creates copies.
66+
For example::
8567

8668
>>> x = np.arange(9).reshape(3, 3)
8769
>>> x
@@ -95,9 +77,9 @@ Advanced indexing, on the other hand, always creates copies. For example::
9577
>>> y.base is None
9678
True
9779

98-
Here, ``y`` is a copy as signified by the base attribute. We can also
99-
confirm this by assigning new values to ``x[[1, 2]]`` which in turn
100-
will not affect ``y`` at all::
80+
Here, ``y`` is a copy, as signified by the :attr:`base <.ndarray.base>`
81+
attribute. We can also confirm this by assigning new values to ``x[[1, 2]]``
82+
which in turn will not affect ``y`` at all::
10183

10284
>>> x[[1, 2]] = [[10, 11, 12], [13, 14, 15]]
10385
>>> x
@@ -139,6 +121,28 @@ shape attribute of the array. For example::
139121
Taking the example of another operation, :func:`.ravel` returns a contiguous
140122
flattened view of the array wherever possible. On the other hand,
141123
:meth:`.ndarray.flatten` always returns a flattened copy of the array.
142-
However, to guarantee a view in most cases ``x.reshape(-1)`` may be preferable.
124+
However, to guarantee a view in most cases, ``x.reshape(-1)`` may be preferable.
143125

126+
How to tell if the array is a view or a copy
127+
============================================
144128

129+
The :attr:`base <.ndarray.base>` attribute of the ndarray makes it easy
130+
to tell if an array is a view or a copy. The base attribute of a view returns
131+
the original array while it returns ``None`` for a copy.
132+
133+
>>> x = np.arange(9)
134+
>>> x
135+
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
136+
>>> y = x.reshape(3, 3)
137+
>>> y
138+
array([[0, 1, 2],
139+
[3, 4, 5],
140+
[6, 7, 8]])
141+
>>> y.base # .reshape() creates a view
142+
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
143+
>>> z = y[[2, 1]]
144+
>>> z
145+
array([[6, 7, 8],
146+
[3, 4, 5]])
147+
>>> z.base is None # advanced indexing creates a copy
148+
True

0 commit comments

Comments
 (0)