# 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 multiplication
result_multiply = arr * 3

# Element-wise square root
result_sqrt = np.sqrt(arr)

print("Original Array:", arr)
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)
``````

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]])

+ 10

print("Original Array:")
print(arr)