Copies and views#

When operating on NumPy arrays, it is possible to access the internal databuffer directly using aview without copying data around. Thisensures good performance but can also cause unwanted problems if the user isnot aware of how this works. Hence, it is important to know the differencebetween these two terms and to know which operations return copies andwhich return views.

The NumPy array is a data structure consisting of two parts:thecontiguous data buffer with the actual data elements and themetadata that contains information about the data buffer. The metadataincludes data type, strides, and other important information that helpsmanipulate thendarray easily. See theInternal organization of NumPy arrayssection for a detailed look.

View#

It is possible to access the array differently by just changing certainmetadata likestride anddtype without changing thedata buffer. This creates a new way of looking at the data and these newarrays are called views. The data buffer remains the same, so any changes madeto a view reflects in the original copy. A view can be forced through thendarray.view method.

Copy#

When a new array is created by duplicating the data buffer as well as themetadata, it is called a copy. Changes made to the copydo not reflect on the original array. Making a copy is slower andmemory-consuming but sometimes necessary. A copy can be forced by usingndarray.copy.

Indexing operations#

Views are created when elements can be addressed with offsets and stridesin the original array. Hence, basic indexing always creates views.For example:

>>>importnumpyasnp>>>x=np.arange(10)>>>xarray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])>>>y=x[1:3]# creates a view>>>yarray([1, 2])>>>x[1:3]=[10,11]>>>xarray([ 0, 10, 11,  3,  4,  5,  6,  7,  8,  9])>>>yarray([10, 11])

Here,y gets changed whenx is changed because it is a view.

Advanced indexing, on the other hand, always creates copies.For example:

>>>importnumpyasnp>>>x=np.arange(9).reshape(3,3)>>>xarray([[0, 1, 2],       [3, 4, 5],       [6, 7, 8]])>>>y=x[[1,2]]>>>yarray([[3, 4, 5],       [6, 7, 8]])>>>y.baseisNoneTrue

Here,y is a copy, as signified by thebaseattribute. We can also confirm this by assigning new values tox[[1,2]]which in turn will not affecty at all:

>>>x[[1,2]]=[[10,11,12],[13,14,15]]>>>xarray([[ 0,  1,  2],       [10, 11, 12],       [13, 14, 15]])>>>yarray([[3, 4, 5],       [6, 7, 8]])

It must be noted here that during the assignment ofx[[1,2]] no viewor copy is created as the assignment happens in-place.

Other operations#

Thenumpy.reshape function creates a view where possible or a copyotherwise. In most cases, the strides can be modified to reshape thearray with a view. However, in some cases where the array becomesnon-contiguous (perhaps after andarray.transpose operation),the reshaping cannot be done by modifying strides and requires a copy.In these cases, we can raise an error by assigning the new shape to theshape attribute of the array. For example:

>>>importnumpyasnp>>>x=np.ones((2,3))>>>y=x.T# makes the array non-contiguous>>>yarray([[1., 1.],       [1., 1.],       [1., 1.]])>>>z=y.view()>>>z.shape=6Traceback (most recent call last):...AttributeError:Incompatible shape for in-place modification. Use`.reshape()` to make a copy with the desired shape.

Taking the example of another operation,ravel returns a contiguousflattened view of the array wherever possible. On the other hand,ndarray.flatten always returns a flattened copy of the array.However, to guarantee a view in most cases,x.reshape(-1) may be preferable.

How to tell if the array is a view or a copy#

Thebase attribute of the ndarray makes it easyto tell if an array is a view or a copy. The base attribute of a view returnsthe original array while it returnsNone for a copy.

>>>importnumpyasnp>>>x=np.arange(9)>>>xarray([0, 1, 2, 3, 4, 5, 6, 7, 8])>>>y=x.reshape(3,3)>>>yarray([[0, 1, 2],       [3, 4, 5],       [6, 7, 8]])>>>y.base# .reshape() creates a viewarray([0, 1, 2, 3, 4, 5, 6, 7, 8])>>>z=y[[2,1]]>>>zarray([[6, 7, 8],       [3, 4, 5]])>>>z.baseisNone# advanced indexing creates a copyTrue

Note that thebase attribute should not be used to determineif an ndarray object isnew; only if it is a view or a copyof another ndarray.