A Beginners Guide to Numpy in Python

Discover NumPy basics in Python! Learn to manipulate data effortlessly with arrays and boost your coding skills. Perfect for beginners diving into numerical computing.

A Beginners Guide to Numpy in Python

Introduction to NumPy: A Beginner’s Guide

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 a collection of mathematical functions to operate on these arrays.

  • In Python we have lists that serve the purpose of arrays, but they are slow to process.

  • NumPy aims to provide an array object that is up to 50x faster than traditional Python lists.

Installation:

Install NumPy using the following command:

Python
pip install numpy
Requirement already satisfied: numpy in /Users/akhilgurrapu/anaconda3/lib/python3.11/site-packages (1.23.5)
Note: you may need to restart the kernel to use updated packages.

Importing NumPy:

Import NumPy in your Python script or Jupyter notebook:

Python
import numpy as np

Key Features:

Arrays:

  • The fundamental data structure in NumPy is the ndarray (N-dimensional array), which is a flexible and efficient container for homogeneous data.
  • Arrays can be created using the numpy.array() function, accepting Python lists or tuples.

Creating Arrays:

Create a simple array:

Python
arr = np.array([1, 2, 3])
arr
array([1, 2, 3])

Note: All the items in the array should be of same data type unlike lists in python.

Python
arr * 2
array([2, 4, 6])

Indexing and Slicing in Array

Python
print(arr[0])       # Access the first element

print(arr[1:3])     # Slice from index 1 to 2
1
[2 3]

NumPy is the ndarray (N-dimensional array)

  • Arrays can be one-dimensional, two-dimensional, or multi-dimensional, depending on the complexity of the data they represent. Understanding array dimensions is crucial for indexing, slicing, and performing operations on arrays.

One-Dimensional Array:

  • An array with a single axis or dimension.
  • Created using a one-dimensional Python list.
Python
one_dimensional_array = np.array([1, 2, 3])
print(one_dimensional_array )

# Accessing elements

print(one_dimensional_array[0])  # Accessing the first element
[1 2 3]
1

Two-Dimensional Array:

  • An array with two axes or dimensions, often representing a matrix.
  • Created using a nested list.
Python
two_dimensional_array = np.array([[1, 2, 3], [4, 5, 6]])
print(two_dimensional_array)

#Accessing elements:

print(two_dimensional_array[0, 1])  # # Accessing the element in the first row and second column
[[1 2 3]
 [4 5 6]]
2
Python
# Extracting a subarray:

two_dimensional_array[0:,1:]
array([[2, 3],
       [5, 6]])

Multi-Dimensional Array:

  • Arrays with more than two dimensions.
  • Created using nested lists with appropriate shapes.
Python
multi_dimensional_array = np.array([[[1, 2, 3, 4], [5, 6, 7 ,8]], [[9, 10, 11, 12], [13, 14, 15, 16]]])

multi_dimensional_array
array([[[ 1,  2,  3,  4],
        [ 5,  6,  7,  8]],

       [[ 9, 10, 11, 12],
        [13, 14, 15, 16]]])
Python
#Accessing elements:

print(multi_dimensional_array[0, 1, 0])  # Accessing the element in the first "layer," second row, and first column
5

Shape of an Array:

  • The shape of an array is a tuple representing the size of each dimension.
  • Obtained using the shape attribute.
Python
print(one_dimensional_array.shape) 
print(two_dimensional_array.shape) 
print(multi_dimensional_array.shape)  
(3,)
(2, 3)
(2, 2, 2)

Reshaping Arrays:

  • To change the shape or dimensions of an array.
  • Use the reshape() function.
Python
original_array = np.array([1, 2, 3, 4, 5, 6])

original_array.reshape((2, 3))

# In this example, the original one-dimensional array is reshaped into a 2x3 matrix.
array([[1, 2, 3],
       [4, 5, 6]])

Transposing Arrays:

  • To interchange rows and columns of a two-dimensional array.
  • Use the .T attribute or the transpose() function.
Python
original_array = np.array([[1, 2, 3], [4, 5, 6]])

original_array.T

#In this example, the original 2x3 matrix is transposed into a 3x2 matrix.
array([[1, 4],
       [2, 5],
       [3, 6]])

Combining Arrays:

  • To concatenate or stack arrays together.
  • Use the concatenate() function.
  • Stacking: Use the vstack() and hstack() functions for vertical and horizontal stacking, respectively.
Python
array1 = np.array([[1, 2], [3, 4]])
array2 = np.array([[5, 6], [7, 8]])

# Concatenation
concatenated_array = np.concatenate((array1, array2), axis=1)

# Horizontal stacking
horizontal_stack = np.hstack((array1, array2))

# Vertical stacking
vertical_stack = np.vstack((array1, array2))

print("Array 1:")
print(array1)

print("\nArray 2:")
print(array2)

print("\nConcatenated Array:")
print(concatenated_array)

print("\nHorizontal Stack:")
print(horizontal_stack)

print("\nVertical Stack:")
print(vertical_stack)
Array 1:
[[1 2]
 [3 4]]

Array 2:
[[5 6]
 [7 8]]

Concatenated Array:
[[1 2 5 6]
 [3 4 7 8]]

Horizontal Stack:
[[1 2 5 6]
 [3 4 7 8]]

Vertical Stack:
[[1 2]
 [3 4]
 [5 6]
 [7 8]]

Broadcasting:

  • Broadcasting is a powerful feature in NumPy that allows for performing element-wise operations on arrays of different shapes and sizes
Python
# Scalar and 1D array broadcasting
scalar_value = 5
array_1d = np.array([1, 2, 3])

result = scalar_value * array_1d
print(result)
[ 5 10 15]
Python
# 1D and 2D array broadcasting
array_1d = np.array([1, 2, 3])
array_2d = np.array([[4, 5, 6], [7, 8, 9]])

result = array_1d + array_2d
print(result)
[[ 5  7  9]
 [ 8 10 12]]
Python
# Broadcasting with reshaping
array_a = np.array([[1], [2], [3]])
array_b = np.array([4, 5, 6])

result = array_a * array_b
print(result)
[[ 4  5  6]
 [ 8 10 12]
 [12 15 18]]

Inbuilt Functions in Numpy

numpy.arange()

  • Creates an array with evenly spaced values within a specified range.
Python
arr = np.arange(1, 10, 2)  # Start at 1, stop before 10, step by 2
print(arr)
[1 3 5 7 9]

numpy.linspace()

  • Creates an array with a specified number of evenly spaced values within a range.
Python
arr = np.linspace(0, 1, 5)  # Start at 0, end at 1, with 5 elements

print(arr)
[0.   0.25 0.5  0.75 1.  ]

numpy.zeros() and numpy.ones()

  • Creates arrays filled with zeros or ones, respectively.
Python
zeros_arr = np.zeros((2, 3))  # 2x3 array of zeros

ones_arr = np.ones((3, 2))   # 3x2 array of ones

print("Zeros Array:")
print(zeros_arr)

print("\nOnes Array:")
print(ones_arr)
Zeros Array:
[[0. 0. 0.]
 [0. 0. 0.]]

Ones Array:
[[1. 1.]
 [1. 1.]
 [1. 1.]]
Python
# Specific Data type can be added to the Zeros and Ones, using 'dtype'

zeros_arr = np.zeros((2, 3), dtype = int)  # 2x3 array of zeros

ones_arr = np.ones((3, 2), dtype = int)   # 3x2 array of ones

print("Zeros Array:")
print(zeros_arr)

print("\nOnes Array:")
print(ones_arr)
Zeros Array:
[[0 0 0]
 [0 0 0]]

Ones Array:
[[1 1]
 [1 1]
 [1 1]]

numpy.random.rand() and numpy.random.randn()

  • Generates random values from a uniform or normal distribution.
Python
random_values = np.random.rand(3, 2)  # 3x2 array of random values [0, 1)

normal_values = np.random.randn(2, 4)  # 2x4 array of random values from a normal distribution

print("Random Values:")
print(random_values)

print("\nNormal Distribution Values:")
print(normal_values)
Random Values:
[[0.6936222  0.88476966]
 [0.17138852 0.42484089]
 [0.29378554 0.82487876]]

Normal Distribution Values:
[[-1.78761297 -0.65459643 -0.55196277 -1.17857765]
 [ 0.01644488  0.22102268 -0.7390483  -1.72983102]]

numpy.random.randint()

  • The numpy.random.randint() function is used to generate random integers from a specified low (inclusive) to a high (exclusive) value. It can generate random integers for a single value, or fill an array with random integers.
Python
# Generate a random integer between 0 (inclusive) and 10 (exclusive)

random_integer = np.random.randint(0, 10)
print("Random Integer:", random_integer)

# Generate a 1D array with 5 random integers between 0 (inclusive) and 10 (exclusive)

random_array = np.random.randint(0, 10, 6)
print("Random Array:", random_array)

#Reshaping the random_array

random_array.reshape(3,2)
Random Integer: 7
Random Array: [9 9 8 8 7 7]


array([[9, 9],
       [8, 8],
       [7, 7]])

numpy.sum(), numpy.mean(), numpy.min(), numpy.max()

  • Compute the sum, mean, minimum, and maximum of an array.
Python
arr = np.array([[1, 2, 3], [4, 5, 6]])

sum_result = np.sum(arr)
mean_result = np.mean(arr)
min_result = np.min(arr)
max_result = np.max(arr)

print("Sum:", sum_result)
print("Mean:", mean_result)
print("Min:", min_result)
print("Max:", max_result)
Sum: 21
Mean: 3.5
Min: 1
Max: 6

Understanding the Distinction Between Assignment (=) and Copy() function

Normal Assignment (=):

  • Creating a reference to the same array.
  • Modifying one variable affects the other.

numpy.copy():

  • Generating a deep copy for an independent array.
  • Modifications to one variable do not impact the other.
Python
# Normal Assignment (=):

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

# Normal assignment, creating a reference to the same array
new_array = original_array

# Modifying the new array
new_array[0, 0] = 100

print("Original Array: after modification of new array")
print(original_array)

print("\nNew Array:")
print(new_array)
Original Array: after modification of new array
[[100   2   3]
 [  4   5   6]]

New Array:
[[100   2   3]
 [  4   5   6]]

new_array is not a new copy of original_array; rather, it’s a reference to the same underlying array.

Python
# numpy.copy():

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

# Create a deep copy using numpy.copy()
copied_array = np.copy(original_array)

# Modify the copied array
copied_array[0, 0] = 100


print("Original Array:")
print(original_array)

print("\nCopied Array:")
print(copied_array)
Original Array:
[[1 2 3]
 [4 5 6]]

Copied Array:
[[100   2   3]
 [  4   5   6]]

using numpy.copy() creates a completely independent copy of the array. Modifying the copied array does not affect the original array, and vice versa.*

Python
import numpy as np

# Scalar and 1D array broadcasting
scalar_value = 5
array_1d = np.array([1, 2, 3])

result = scalar_value * array_1d
print(result)
[ 5 10 15]
Python
import numpy as np

# 1D and 2D array broadcasting
array_1d = np.array([1, 2, 3])
array_2d = np.array([[4, 5, 6], [7, 8, 9]])

result = array_1d + array_2d
print(result)
[[ 5  7  9]
 [ 8 10 12]]
Python
import numpy as np

# Broadcasting with reshaping
array_a = np.array([[1], [2], [3]])
array_b = np.array([4, 5, 6])

result = array_a * array_b
print(result)
[[ 4  5  6]
 [ 8 10 12]
 [12 15 18]]