# How To Use Numpy In Python?

NumPy, short for Numerical Python, is a powerful library in Python for numerical and mathematical operations.

It provides support for large, multi-dimensional arrays and matrices, along with an extensive collection of high-level mathematical functions to operate on these arrays.

In this comprehensive guide, we'll explore the fundamentals of NumPy, covering array creation, manipulation, mathematical operations, and more.

## Installing NumPy:

Before diving into NumPy, ensure that it is installed in your Python environment. You can install it using the following command:

```
pip install numpy
```

## NumPy Basics:

### Importing NumPy:

Once installed, you can import NumPy into your Python script or Jupyter notebook:

```
import numpy as np
```

The common convention is to import NumPy with the alias `np`

for brevity.

### Creating NumPy Arrays:

NumPy arrays are the fundamental data structure in NumPy, providing a way to represent and manipulate numerical data efficiently.

#### 1. Creating Arrays from Lists:

```
import numpy as np
# 1D array
arr_1d = np.array([1, 2, 3])
# 2D array (matrix)
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
# 3D array
arr_3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
```

#### 2. Using NumPy Functions:

```
import numpy as np
# Create an array of zeros
zeros_arr = np.zeros((2, 3))
# Create an array of ones
ones_arr = np.ones((3, 4))
# Create an identity matrix
identity_matrix = np.eye(3)
```

### Array Attributes:

NumPy arrays have several attributes that provide information about their shape, size, and data type.

```
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print("Shape:", arr.shape) # Output: (2, 3)
print("Number of Dimensions:", arr.ndim) # Output: 2
print("Data Type:", arr.dtype) # Output: int64
print("Size:", arr.size) # Output: 6
```

## Array Indexing and Slicing:

### Indexing:

NumPy arrays are zero-indexed, and you can access individual elements using indexing:

```
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Accessing the first element
print(arr[0]) # Output: 1
# Accessing the last element
print(arr[-1]) # Output: 5
```

### Slicing:

You can slice NumPy arrays to extract subarrays:

```
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Slicing to get a subarray
subarr = arr[1:4]
print(subarr) # Output: [2, 3, 4]
```

## Mathematical Operations:

NumPy provides a wide range of mathematical functions for array operations. These functions are optimized for performance and operate element-wise.

```
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Element-wise addition
result_addition = arr + 2
# Element-wise multiplication
result_multiply = arr * 3
# Element-wise square root
result_sqrt = np.sqrt(arr)
print("Original Array:", arr)
print("After Addition:", result_addition)
print("After Multiplication:", result_multiply)
print("Square Root:", result_sqrt)
```

## Linear Algebra with NumPy:

NumPy is widely used in linear algebra operations, making it a powerful tool for scientific computing.

### Matrix Multiplication:

```
import numpy as np
matrix_a = np.array([[1, 2], [3, 4]])
matrix_b = np.array([[5, 6], [7, 8]])
result_matrix_mult = np.dot(matrix_a, matrix_b)
print("Matrix A:")
print(matrix_a)
print("Matrix B:")
print(matrix_b)
print("Result of Matrix Multiplication:")
print(result_matrix_mult)
```

### Transposing a Matrix:

```
import numpy as np
matrix = np.array([[1, 2, 3], [4, 5, 6]])
transposed_matrix = np.transpose(matrix)
print("Original Matrix:")
print(matrix)
print("Transposed Matrix:")
print(transposed_matrix)
```

## Random Sampling with NumPy:

NumPy provides functions for random sampling, allowing you to generate arrays with random values.

### Generating Random Numbers:

```
import numpy as np
# Generate random numbers from a uniform distribution
random_uniform = np.random.rand(3, 4)
# Generate random integers within a specified range
random_integers = np.random.randint(low=1, high=10, size=(2, 3))
print("Random Numbers (Uniform Distribution):")
print(random_uniform)
print("Random Integers:")
print(random_integers)
```

### Shuffling Arrays:

```
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Shuffle the array in-place
np.random.shuffle(arr)
print("Shuffled Array:")
print(arr)
```

## Broadcasting:

NumPy allows broadcasting, a powerful mechanism that enables operations on arrays of different shapes and sizes.

```
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
# Broadcasting: Adding a scalar to each element
result_broadcasting = arr
+ 10
print("Original Array:")
print(arr)
print("Result after Broadcasting:")
print(result_broadcasting)
```

## Conclusion:

NumPy is an indispensable library for numerical and scientific computing in Python.

Its ability to handle large arrays efficiently, perform mathematical operations, and support linear algebra makes it a go-to tool for data scientists, engineers, and researchers.

By mastering the basics of NumPy, you empower yourself to tackle a wide range of computational tasks and unlock the full potential of Python for scientific and numerical computing.