# NumPy - Copies & Views

While working with various functions in Python, there are functions which return a copy of the input array, while some return the view.

The copy owns the data and any changes made to the copy will not affect original array, and any changes made to the original array will not affect the copy.

The view does not own the data and any changes made to the view will affect the original array, and any changes made to the original array will affect the view.

## No copy

Array object created using simple assignment operator do not create the copy of array object. Instead, it shares the same id as the original array. The id of a Python object is very much similar to the pointer in C. Furthermore, any changes in either gets reflected in the other.

### Example:

In the example below, an array is created using simple assignment operator and changing shape of one array is also changing the shape of another array.

```import numpy as np

x = np.array([[1,2,3],
[4,5,6]])

#creating a view of array x
y = x

#displaying array x
print("id of x =", id(x))
print("x =")
print(x)

#displaying array y
print("\nid of y =", id(y))
print("y =")
print(y)

#changing content of y
#this will change x and y both
y[0,0] = 100

#after operation, array x
print("\nx =")
print(x)

#after operation, array y
print("\ny =")
print(y)
```

The output of the above code will be:

```id of x = 140318694401200
x =
[[1 2 3]
[4 5 6]]

id of y = 140318694401200
y =
[[1 2 3]
[4 5 6]]

x =
[[100   2   3]
[  4   5   6]]

y =
[[100   2   3]
[  4   5   6]]
```

## Shallow copy

The NumPy ndarray.view() returns a view (shallow copy) of the array. The created view has different id but any changes made to the view will affect the original array. The syntax for using this function is given below:

### Syntax

```numpy.ndarray.view([dtype][, type])
```

### Parameters

 `dtype` `Optional. `Specify data-type descriptor of the returned view, e.g., float32 or int16. Omitting it results in the view having the same data-type as the original array. `type` `Optional. `Specify type of the returned view, e.g., ndarray or matrix. Again, omission of the parameter results in type preservation.

### Return Value

Returns a view of the array.

### Example:

In the example below, ndarray.view() is used to create a view (shallow copy) of a given array.

```import numpy as np

x = np.array([[1,2,3],
[4,5,6]])

#creating a view of array x
y = x.view()

#displaying array x
print("id of x =", id(x))
print("x =")
print(x)

#displaying array y
print("\nid of y =", id(y))
print("y =")
print(y)

#changing content of y
#this will change x and y both
y[0,0] = 100

#after operation, array x
print("\nx =")
print(x)

#after operation, array y
print("\ny =")
print(y)
```

The output of the above code will be:

```id of x = 140004172440752
x =
[[1 2 3]
[4 5 6]]

id of y = 140004172443536
y =
[[1 2 3]
[4 5 6]]

x =
[[100   2   3]
[  4   5   6]]

y =
[[100   2   3]
[  4   5   6]]
```

## Deep copy

The NumPy ndarray.copy() returns a deep copy of the array. The syntax for using this function is given below:

### Syntax

```numpy.ndarray.copy(order='C')
```

### Parameters

 `order` `Optional. `Specify the memory layout of the copy. It can take values from {'C', 'F', 'A', 'K'}. The default is 'C'. 'C' - for C order (row major). 'F' - for F order (column major). 'A' - F if a is Fortran contiguous, C otherwise. 'K' - match the layout of a as closely as possible.

### Example:

In the example below, ndarray.copy() is used to copy a given array.

```import numpy as np

x = np.array([[1,2,3],
[4,5,6]])

#creating a copy of array x
y = x.copy()

#displaying array x
print("id of x =", id(x))
print("x =")
print(x)

#displaying array y
print("\nid of y =", id(y))
print("y =")
print(y)

#changing content of y
#this will change y but not x
y[0,0] = 100

#after operation, array x
print("\nx =")
print(x)

#after operation, array y
print("\ny =")
print(y)
```

The output of the above code will be:

```id of x = 140389488063664
x =
[[1 2 3]
[4 5 6]]

id of y = 140389488066448
y =
[[1 2 3]
[4 5 6]]

x =
[[1 2 3]
[4 5 6]]

y =
[[100   2   3]
[  4   5   6]]
```

5