# NumPy Copy vs View

When working with Numpy, we come across two terms, Numpy Copy and Numpy View. While both of the terms seem quite similar at a glance, they have different functionalities and use cases.

## What are Numpy Copy and Numpy View?

Numpy Copy and Numpy View are both methods of creating a new array with the same data, but they have some key differences:

Numpy Copy: This method creates a new array with a new memory block and copies the original data to it.

Numpy View: This method creates a new array that shares the same memory block as the original array.

## Numpy Copy

Numpy Copy method creates a new array with a new memory block and copies the original data to it. Thus, we can modify the new array without affecting the original array.

Let’s first create a numpy array:

```import numpy as np

a = np.array([1,2,3,4,5])```

We can create a copy of this array using np.copy():

```# Creating a copy of numpy array
b = np.copy(a)
print(f"a = {a}")
print(f"b = {b}")```

This will generate the following output:

```a = [1 2 3 4 5]
b = [1 2 3 4 5]```

As we can observe, both a and b have the same elements, but they have different memory locations.

Let’s modify the new array b using:

```b[0] = 13
print(f"a = {a}")
print(f"b = {b}")```

This will generate the following output:

```a = [1 2 3 4 5]
b = [13  2  3  4  5]```

As we can see, modifying b only affected b, and not a as it has its own unique memory location.

## Numpy View

Numpy View method creates a new array that shares the same memory block as the original array. Thus, any modification in the new array would affect the original array as well.

Let’s again create a numpy array:

```import numpy as np

a = np.array([1,2,3,4,5])```

We can create a view of this array using np.view():

```# Creating a view of numpy array
b = a.view()
print(f"a = {a}")
print(f"b = {b}")```

This will generate the following output:

```a = [1 2 3 4 5]
b = [1 2 3 4 5]```

Both a and b have the same elements and the same memory location. Let’s modify b using:

```b[0] = 13
print(f"a = {a}")
print(f"b = {b}")```

This will generate the following output:

```a = [13  2  3  4  5]
b = [13  2  3  4  5]```

As we can see, modifying b affected a as well, because they both share the same memory location.

## Example:

```# Numpy Copy
import numpy as np

a = np.array([1, 2, 3])
b = np.copy(a)

print(a) # Output: [1 2 3]
print(b) # Output: [1 2 3]

b[0] = 4

print(a) # Output: [1 2 3]
print(b) # Output: [4 2 3]

# Numpy view
a = np.array([1, 2, 3])
b = a.view()

print(a) # Output: [1 2 3]
print(b) # Output: [1 2 3]

b[0] = 4

print(a) # Output: [4 2 3]
print(b) # Output: [4 2 3]
```

## Conclusion

Memory management is quite important when working with large data sets. Numpy provides different methods to handle memory management. Numpy Copy and Numpy View methods are very useful, but they have different functionalities and use cases, which makes them ideal for different scenarios.