Lesson 4 - Copies and Views

The original tutorial may be found here.

When operating and manipulating arrays, their data is sometimes copied into a new array and sometimes not. This is often a source of confusion for beginners. There are three cases:

  • No Copy at All
  • View or Shallow Copy
  • Deep Copy
In [1]:
import numpy as np

No Copy at All

Simple assignments make no copy of array objects or of their data.

In [2]:
a = np.arange(12)
In [3]:
a
Out[3]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
In [4]:
b = a            # no new object is created
In [5]:
b is a           # a and b are two names for the same ndarray object
Out[5]:
True
In [6]:
b.shape = 3, 4
In [7]:
b
Out[7]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [8]:
a
Out[8]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

Python passes mutable objects as references, so function calls make no copy.

In [9]:
def f(x):
    print id(x)
In [10]:
id(a)
Out[10]:
65508416L
In [11]:
f(a)
65508416

View or Shallow Copy

Different array objects can share the same data. The view method creates a new array object that looks at the same data.

In [12]:
c = a.view()
In [15]:
c is a
Out[15]:
False
In [16]:
c.base is a                        # c is a view of the data owned by a
Out[16]:
True
In [17]:
c.flags.owndata
Out[17]:
False
In [18]:
c.shape = 2,6                      # a's shape doesn't change
In [19]:
a
Out[19]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [20]:
c
Out[20]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])
In [22]:
c[0,4] = 1234     # a's data changes
In [23]:
a
Out[23]:
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])
In [25]:
c
Out[25]:
array([[   0,    1,    2,    3, 1234,    5],
       [   6,    7,    8,    9,   10,   11]])

Deep Copy

The copy method makes a complete copy of the array and its data.

In [27]:
d = a.copy()       # a new array object with new data is created
In [28]:
d is a
Out[28]:
False
In [29]:
d.base is a                           # d doesn't share anything with a
Out[29]:
False
In [30]:
d[0,0] = 9999
In [31]:
a
Out[31]:
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])
In [32]:
d
Out[32]:
array([[9999,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])

Conclusion

We have now completed the Tutorial Lesson 4 - Copies and Views