Views and copies

There are primarily two ways of accessing data by slicing and indexing. They are called copies and views: you can either access elements directly from an array, or create a copy of the array that contains only the accessed elements. Since a view is a reference of the original array (in Python, all variables are references), modifying a view modifies the original array too. This is not true for copies.

The may_share_memory function in NumPy miscellaneous routines can be used to determine whether two arrays are copies or views of each other. While this method does the job in most cases, it is not always reliable, since it uses heuristics. It may return incorrect results too. For introductory purposes, however, we shall take it for granted.

Generally, slicing an array creates a view and indexing it creates a copy. Let us study these differences through a few code snippets. First, let's create a random 100x10 array.

In [21]: x = np.random.rand(100,10) 

Now, let us extract the first five rows of the array and assign them to variable y.

In [22]: y = x[:5, :] 

Let us see if y is a view of x.

In [23]: np.may_share_memory(x, y) 
 
Out[23]: True 

Now let us modify the array y and see how it affects x. Set all the elements of y to zero:

In [24]: y[:] = 0 
 
In [25]: print(x[:5, :]) 
Out[25]: [[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.] 
[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.] 
[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.] 
[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.] 
          [ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.]] 

The code snippet prints out five rows of zeros. This is because y was just a view, a reference to x.

Next, let's create a copy to see the difference. We use the preceding method that uses a random function to create the x array, but this time we initialize the y array using numpy.empty to create an empty array first and then copy the values from x to y. So, now y is not a view/reference of x anymore; it's an independent array but has the same values as part of x. Let's use the may_share_memory function again to verify that y is the copy of x:

In [26]: x = np.random.rand(100,10) 
 
In [27]: y = np.empty([5, 10]) 
 
In [28]: y[:] = x[:5, :] 
 
In [29]: np.may_share_memory(x, y) 
Out[29]: False 

Let's alter the value in y and check whether the value of x changes as well:

In [30]: y[:] = 0 
In [31]: print(x[:5, :]) 

You should see the preceding snippet print out five rows of random numbers as we initialized x, so changing y to 0 didn't affect x.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.228.78