Numpy Module
Numpy Module
An array is a data type used to store multiple values using a single identifier (variable name).
An array contains an ordered collection of data elements where each element is of the same
type and can be referenced by its index (position).
The important characteristics of an array are:
• Each element of the array is of same data type, though the values stored in them may
be different.
• The entire array is stored contiguously in memory. This makes operations on array fast.
• Each element of the array is identified or referred using the name of the Array along
with the index of that element, which is unique for each element. The index of an
element is an integral value associated with the element, based on the element’s
position in the array.
For example consider an array with 5 numbers:
[ 10, 9, 99, 71, 90 ]
Zero based indexing is used to access array elements. For eg. index 0 represents the first
element, 1 represents the second element and so on. Backward indexing starts from -1 at the
last element of the array and decreases by 1 towards the left of the array. This is very similar to
the indexing of lists in Python.
● The array module in Python provides an efficient way to store homogeneous data
(all elements of the same type).
● It is built -in module to create and manipulate ID (one Dimensional) Arrays.
● It is more memory-efficient than lists but less powerful than NumPy arrays.
● Each array requires a type code (like 'i' for integers, 'f' for floats).
Creating Arrays
Syntax:
[Link](typecode, initializer)
● typecode: A single character code that specifies the type of
array elements.
Example:
import array
Output:
Attributes of array
arr = [Link]('i', [1,2,3,4])
print([Link]) # 'i' → type of elements
print([Link]) # 4 → bytes per element
print(arr.buffer_info()) # (address, length)
print(len(arr)) # 4
Output:
i
4
(1763652116544, 4)
4
Methods of array
(a) Append
[Link](5)
print(arr) # array('i', [1,2,3,4,5])
(b) Extend
[Link]([6,7])
print(arr) # array('i', [1,2,3,4,5,6,7])
(c) Insert
[Link](1, 99)
print(arr) # array('i', [1,99,2,3,4,5,6,7])
(d) Remove
[Link](3)
print(arr) # array('i', [1,99,2,4,5,6,7])
(e) Pop
x = [Link](2)
print(x) # 2
print(arr) # array('i', [1,99,4,5,6,7])
(f) Index
print([Link](99)) # 1
(g) Reverse
[Link]()
print(arr)
(h) Count
print([Link](5)) # 1
7. Iteration
for x in arr:
print(x, end=" ")
Output:
7 6 5 4 99 1
Operations on Arrays
(a) Concatenation
a1 = [Link]('i', [1,2,3])
a2 = [Link]('i', [4,5])
a3 = a1 + a2
print(a3) # array('i', [1,2,3,4,5])
(b) Repetition
print(a1 * 2) # array('i', [1,2,3,1,2,3])
(c) Slicing
print(a3[1:4]) # array('i', [2,3,4])
NUMPY Module
NumPy (Numerical Python) is a powerful Python library used for numerical and
scientific computing. It provides support for arrays, matrices, and a collection of
mathematical functions to operate on these data structures efficiently.
Key Features of NumPy:
1. N-dimensional Array Object (ndarray): At its core, NumPy provides a
powerful n-dimensional array object that allows for fast and efficient
handling of large datasets.
2. Mathematical Functions: NumPy includes a wide variety of built-in
mathematical functions, such as linear algebra operations, Fourier
transforms, and random number generation.
3. Broadcasting: It supports broadcasting, allowing operations on arrays of
different shapes without needing to explicitly reshape them.
4. Integration with Other Libraries: Many popular scientific computing
libraries like SciPy, pandas, and machine learning frameworks like
TensorFlow rely on NumPy arrays for their underlying data structures.
5. Memory Efficiency: Compared to Python lists, NumPy arrays use much less
memory and provide better performance for large datasets.
Advantages of NumPy:
1. Performance: NumPy is written in C and Fortran, making it much faster than
native Python for large computations, especially with vectorized operations
(i.e., applying operations on entire arrays instead of using loops).
2. Efficient Storage: Arrays in NumPy are stored more efficiently than Python
lists because they use fixed data types (e.g., integers, floats), leading to
lower memory consumption.
3. Easy Array Operations: NumPy allows for a wide range of mathematical
operations on arrays, such as element-wise addition, subtraction,
multiplication, and division, without the need for explicit loops. This makes
code simpler and more readable.
4. Multi-Dimensional Arrays: It simplifies working with multi-dimensional
arrays (matrices, tensors) and provides built-in functions for reshaping,
splitting, stacking, and transposing arrays.
5. Cross-Library Compatibility: NumPy arrays are the standard for numerical
data and are seamlessly integrated with many other Python libraries,
making it easier to switch between different libraries for data analysis and
machine learning.
6. Support for Advanced Functions: It includes advanced functions like:
o Linear algebra functions: Determinants, eigenvalues, matrix
inversions.
o Fourier Transforms: Discrete Fourier transforms.
o Random Number Generation: For simulations and probabilistic
computations.
7. Data Analysis and Machine Learning: Due to its efficiency and flexibility,
NumPy is used in data science workflows, particularly for pre-processing
data and performing operations before feeding data into machine learning
algorithms.
In summary, NumPy is an essential tool for scientific and numerical computation
in Python, allowing users to perform high-performance operations on large
datasets easily.
ndarray
An ndarray (N-dimensional array) is the fundamental data structure in NumPy
used for scientific and numerical [Link] represents a multi-dimensional,
homogeneous array of fixed-size items. All elements in an ndarray must be of the
same type (e.g., integers, floats), and it supports efficient operations on large
datasets.
It:
Example:
import numpy as np
print([Link]) # (2, 3)
print([Link]) # int64
dtype in NumPy
● A dtype (short for data-type object) is a NumPy object that specifies how
data in an ndarray is stored and interpreted. It describes the type and
size of elements stored in a NumPy ndarray.
● It defines the type of data (int, float, string, etc.).
It ensures all elements in an ndarray have the same type for efficiency.
b Boolean True/False
Example
import numpy as np
arr = [Link]([1, 2, 3], dtype=np.int32)
print(arr) # [1 2 3]
2. Manipulating 2D Arrays
(c) Slicing
arr[0:2, 1:3] # submatrix (rows 0-1, cols 1-2)
(d) Reshaping
[Link](3, 2) # reshape into 3x2
(e) Transpose
arr.T
(f) Stacking
Indexing in numpy
Indexing in NumPy refers to accessing individual elements or groups of elements
(subarrays) within a NumPy array using their positions (indices). NumPy supports
various forms of indexing, making it highly versatile and efficient.
Indexing Techniques in NumPy:
● Basic Indexing: Access single elements using [index] operator.
● Negative indexing: Allows to access elements from the end of an array,
rather than the beginning.
● Slicing: Access ranges of elements using slicing operator [start:stop:step].
● Boolean Indexing: Access elements that meet a specific condition using a
boolean mask.
● Fancy Indexing: Access elements using arrays of indices.
● Mixed Indexing: Combine different types of indexing for complex
operations.
These techniques allow NumPy arrays to be sliced, filtered, and accessed with
high flexibility, making them powerful for data analysis and manipulation.
Here's a detailed explanation of the different types of indexing in NumPy:
1. Basic Indexing
Example:
import numpy as np
arr = [Link]([10, 20, 30, 40, 50])
10
30
50
Output:
[20 30 40]
[10 20 30]
[30 40 50]
[10 30 50]
Example:
arr2d = [Link]([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
● Row index = 0, 1, 2
● Column index = 0, 1, 2
Output:
1
6
9
Output:
[1 2 3]
[4 5 6]
Output:
[1 4 7]
[2 5 8]
Output:
[[2 3]
[5 6]]
[[4 5]
[7 8]]
Output:
[[1 3]
[7 9]]
2. Boolean Indexing
Boolean indexing allows you to access elements based on conditions. This is
especially useful for filtering arrays.
2.1. Boolean Indexing in 1D Arrays
# Boolean array where elements are greater than 25
condition = array_1d > 25
print("Boolean Mask:", condition)
# Use the condition to get elements greater than 25
filtered_array = array_1d[condition]
print("Filtered Array (Elements > 25):", filtered_array)
Output:
Boolean Mask: [False False True True True]
Filtered Array (Elements > 25): [30 40 50]
2.2. Boolean Indexing in 2D Arrays
# Condition: elements greater than 5
condition_2d = array_2d > 5
print("Boolean Mask 2D:\n", condition_2d)
# Use the condition to get elements greater than 5
filtered_2d = array_2d[condition_2d]
print("\nFiltered 2D Array (Elements > 5):", filtered_2d)
Output:
Boolean Mask 2D:
[[False False False]
[False False True]
[ True True True]]
Filtered 2D Array (Elements > 5): [6 7 8 9]
3. Fancy Indexing
Fancy indexing allows you to select specific elements using arrays of indices.
3.1. Fancy Indexing in 1D Arrays
python
Copy code
# Create a list of indices
indices = [0, 2, 4]
# Use the indices to access specific elements
fancy_1d = array_1d[indices]
print("Fancy Indexed 1D Array:", fancy_1d)
Output:
Fancy Indexed 1D Array: [10 30 50]
3.2. Fancy Indexing in 2D Arrays
# Create lists of row and column indices
rows = [0, 1, 2]
columns = [1, 2, 0]
# Use the lists of indices to access specific elements
fancy_2d = array_2d[rows, columns]
print("Fancy Indexed 2D Array:", fancy_2d)
Output:
Fancy Indexed 2D Array: [2 6 7]
4. Mixed Indexing
You can combine different types of indexing (basic, slicing, boolean, fancy) for
complex selections.
Example of Mixed Indexing
# Slice the first two rows, then apply boolean indexing
mixed_indexing = array_2d[0:2, :][array_2d[0:2, :] > 2]
print("Mixed Indexing Result:", mixed_indexing)
Output:
Mixed Indexing Result: [3 4 5 6]
Slicing in numpy
Slicing in NumPy refers to extracting a subset of elements from an array. It allows
for efficient access to specific elements, rows, or columns of an array without
modifying the original array. Slicing is done using the colon (:) operator, and you
can define a range for each axis in a multi-dimensional array.
1. Slicing in 1D Arrays
A 1D NumPy array behaves similarly to a Python list when it comes to slicing. You
can use the basic syntax [start:stop:step] to slice the array.
● start: The index at which slicing starts (inclusive).
● stop: The index at which slicing stops (exclusive).
● step: The number of steps between elements (default is 1).
Example 1.1: Basic Slicing
import numpy as np
# Create a 1D array
array_1d = [Link]([10, 20, 30, 40, 50, 60])
# Slice elements from index 1 to 4 (exclusive)
slice_1d = array_1d[1:4]
print("Sliced 1D Array:", slice_1d)
Output:
Sliced 1D Array: [20 30 40]
Example 1.2: Slicing with Steps
You can specify a step to select every nth element within the slice.
# Slice every second element from index 0 to 5
slice_with_step = array_1d[0:5:2]
print("Sliced 1D Array with Step:", slice_with_step)
Output:
Sliced 1D Array with Step: [10 30 50]
Example 1.3: Omitting start or stop
● If start is omitted, it defaults to the beginning of the array.
● If stop is omitted, it defaults to the end of the array.
# Slice from the beginning to index 3 (exclusive)
slice_omit_start = array_1d[:3]
print("Sliced Array (Start Omitted):", slice_omit_start)
# Slice from index 2 to the end of the array
slice_omit_stop = array_1d[2:]
print("Sliced Array (Stop Omitted):", slice_omit_stop)
Output:
Sliced Array (Start Omitted): [10 20 30]
Sliced Array (Stop Omitted): [30 40 50 60]
Example 1.4: Negative Indexing in Slicing
You can use negative indices to slice elements from the end of the array.
# Slice the last three elements
slice_negative = array_1d[-3:]
print("Sliced Array with Negative Indices:", slice_negative)
Output:
Sliced Array with Negative Indices: [40 50 60]
2. Slicing in 2D Arrays
In a 2D array, slicing allows you to select specific rows, columns, or subarrays. You
can specify slicing for each dimension separately using [row_start:row_stop,
col_start:col_stop].
Example 2.1: Basic Slicing in 2D Arrays
# Create a 2D array (3 rows, 4 columns)
array_2d = [Link]([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
# Slice a subarray: first two rows, first three columns
slice_2d = array_2d[0:2, 0:3]
print("Sliced 2D Array (First Two Rows, First Three Columns):")
print(slice_2d)
Output:
Sliced 2D Array (First Two Rows, First Three Columns):
[[1 2 3]
[5 6 7]]
Example 2.2: Slicing Rows and Columns
You can slice specific rows or columns by omitting the other dimension.
# Slice all rows, and the first two columns
slice_columns = array_2d[:, 0:2]
print("Sliced 2D Array (All Rows, First Two Columns):")
print(slice_columns)
# Slice the first two rows, and all columns
slice_rows = array_2d[0:2, :]
print("Sliced 2D Array (First Two Rows, All Columns):")
print(slice_rows)
Output:
Sliced 2D Array (All Rows, First Two Columns):
[[ 1 2]
[ 5 6]
[ 9 10]]
Sliced 2D Array (First Two Rows, All Columns):
[[1 2 3 4]
[5 6 7 8]]
Example 2.3: Using Negative Indices in 2D Arrays
Negative indices can be used in both row and column slicing to select elements
from the end of the array.
# Slice the last two rows and last two columns
slice_negative_2d = array_2d[-2:, -2:]
print("Sliced 2D Array (Last Two Rows, Last Two Columns):")
print(slice_negative_2d)
Output:
Sliced 2D Array (Last Two Rows, Last Two Columns):
[[ 7 8]
[11 12]]
Example 2.4: Slicing Subarrays
You can extract specific subarrays from a 2D array.
# Extract a 2x2 subarray from the bottom-left corner
subarray = array_2d[1:3, 0:2]
print("Extracted Subarray (2x2 from Bottom-Left Corner):")
print(subarray)
Output:
Extracted Subarray (2x2 from Bottom-Left Corner):
[[ 5 6]
[ 9 10]]
3. Slicing with Steps
You can use the step argument in any dimension to select elements at regular
intervals.
Example 4.1: Slicing with Steps in 1D Arrays
# Slice every second element
step_slice_1d = array_1d[::2]
print("Sliced 1D Array with Steps:", step_slice_1d)
Output:
Sliced 1D Array with Steps: [10 30 50]
Example 4.2: Slicing with Steps in 2D Arrays
# Slice every second row and every second column
step_slice_2d = array_2d[::2, ::2]
print("Sliced 2D Array with Steps (Every Second Row and Column):")
print(step_slice_2d)
Output:
Sliced 2D Array with Steps (Every Second Row and Column):
[[ 1 3]
[ 9 11]]
Iterating in numpy
Iterating over NumPy arrays involves processing elements of the array one by one,
which can be done using loops. NumPy supports efficient iteration over arrays
using Python's for loop. However, the iteration behavior depends on the array’s
dimensions and shape.
● 1D arrays: Iteration is straightforward, similar to Python lists.
● 2D and higher-dimensional arrays: Single loops iterate over rows; nested
loops or nditer() can be used to iterate over individual elements.
● Modifying elements: nditer() with op_flags=['readwrite'] allows in-place
modification.
● Indexing during iteration: ndenumerate() allows access to both indices and
values during iteration.
● Broadcasting: nditer() can iterate over arrays of different shapes by
broadcasting.
These techniques make it easy to access and manipulate elements efficiently in
NumPy arrays.
import numpy as np
arr = [Link]([10, 20, 30, 40])
for x in arr:
print(x)
Output:
10
20
30
40
Output:
[1 2 3]
[4 5 6]
Output:
1
2
3
4
5
6
for x in [Link](arr2d):
print(x)
Output:
1
2
3
4
5
6
Output:
(0, 0) 10
(0, 1) 20
(1, 0) 30
(1, 1) 40
Output:
2 is even
4 is even
Copying in numpy
When you work with arrays, sometimes you want:
import numpy as np
a = [Link]([1, 2, 3])
b = a # no copy
b[0] = 99
print("a:", a) # [99 2 3]
print("b:", b) # [99 2 3]
● Explanation: Creates a new array object, but it shares the same data.
a = [Link]([1, 2, 3])
b = [Link]()
b[0] = 99
print("a:", a) # [99 2 3]
print("b:", b) # [99 2 3]
[Link] = (3, 1)
print("[Link]:", [Link]) # (3,)
print("[Link]:", [Link]) # (3,1)
a = [Link]([1, 2, 3])
b = [Link]()
b[0] = 99
print("a:", a) # [1 2 3]
print("b:", b) # [99 2 3]
b[0] = 99
print("a:", a) # [10 99 30 40]
print("b:", b) # [99 30]
a = [Link]([1, 2, 3])
b = [Link](a)
b[1] = 77
print("a:", a) # [1 2 3]
print("b:", b) # [1 77 3]
import numpy as np
print(splits)
Output:
print(splits)
Output:
2. Splitting 2D Arrays
Example Array:
arr2d = [Link]([[1, 2, 3, 4],
[5, 6, 7, 8]])
print(arr2d)
Output:
[[1 2 3 4]
[5 6 7 8]]
● Splits columns.
splits = [Link](arr2d, 2)
print(splits[0])
print(splits[1])
Output:
[[1 2]
[5 6]]
[[3 4]
[7 8]]
● Splits rows.
splits = [Link](arr2d, 2)
print(splits[0])
print(splits[1])
Output:
[[1 2 3 4]]
[[5 6 7 8]]
Output:
[array([[1, 2],
[5, 6]]), array([[3, 4],
[7, 8]])]
1. Shape Basics
Example:
import numpy as np
arr = [Link]([[1, 2, 3], [4, 5, 6]])
print([Link]) # (2, 3) → 2 rows, 3 columns
2. Reshape (reshape())
Output:
Original: [0 1 2 3 4 5]
Reshaped:
[[0 1 2]
[3 4 5]]
Output:
Original:
[[1 2 3]
[4 5 6]]
Reshaped: [1 2 3 4 5 6]
Output:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
3. Flattening an Array
4. Transpose (T)
Output:
Original:
[[1 2 3]
[4 5 6]]
Transpose:
[[1 4]
[2 5]
[3 6]]
5. Resizing (resize())
Output:
[[1 2 3]
[4 1 2]]
Summary :
Syntax:
[Link](arr1, arr2) # or arr1 + arr2
Example:
import numpy as np
print(arr1 + arr2)
print([Link](arr1, arr2))
Output:
[5 7 9]
[5 7 9]
Syntax:
[Link](arr1, arr2) # or arr1 - arr2
Example:
print(arr1 - arr2)
print([Link](arr1, arr2))
Output:
[-3 -3 -3]
[-3 -3 -3]
3. Multiplication -Multiplies each element.
Syntax:
[Link](arr1, arr2) # or arr1 * arr2
Example:
print(arr1 * arr2)
print([Link](arr1, arr2))
Output:
[ 4 10 18]
[ 4 10 18]
Syntax:
[Link](arr1, arr2) # or arr1 / arr2
Example:
print(arr2 / arr1)
print([Link](arr2, arr1))
Output:
[4. 2.5 2. ]
[4. 2.5 2. ]
Syntax:
np.floor_divide(arr1, arr2) # or arr1 // arr2
Example:
print(arr2 // arr1)
print(np.floor_divide(arr2, arr1))
Output:
[4 2 2]
[4 2 2]
Syntax:
[Link](arr1, arr2) # or arr1 % arr2
Example:
print(arr2 % arr1)
print([Link](arr2, arr1))
Output:
[0 1 0]
[0 1 0]
Syntax:
[Link](arr1, arr2) # or arr1 ** arr2
Example:
print(arr1 ** 2) # square
Output:
[1 4 9]
[ 1 32 729]
8. Absolute Value
Syntax:
[Link](arr) # absolute values
Example:
arr3 = [Link]([-1, -2, 3])
print([Link](arr3))
Output:
[1 2 3]
9. Reciprocal
Syntax:
[Link](arr)
Example:
arr4 = [Link]([1, 2, 4])
print([Link](arr4))
Output:
[1 0 0]
print([Link](arr5))
Output:
print(arr1 + 5) # [6 7 8]
print(arr1 * 2) # [2 4 6]
print(arr1 ** 3) # [1 8 27]
Summary
1. Matrix Creation
import numpy as np
A = [Link]([[1, 2],
[3, 4]])
B = [Link]([[5, 6],
[7, 8]])
print("Matrix A:\n", A)
print("Matrix B:\n", B)
2. Element-wise Operations
These are applied element by element (not true matrix multiplication).
print(A + B) # Addition
print(A - B) # Subtraction
print(A * B) # Element-wise multiplication
print(A / B) # Element-wise division
Output:
[[ 6 8]
[10 12]]
[[-4 -4]
[-4 -4]]
[[ 5 12]
[21 32]]
[[0.2 0.33333333]
[0.42857143 0.5 ]]
3. Matrix Multiplication
True matrix multiplication = dot product.
Method 1: [Link]()
print([Link](A, B))
Method 2: @ operator
print(A @ B)
Output:
[[19 22]
[43 50]]
4. Transpose
Swaps rows and columns.
print(A.T)
Output:
[[1 3]
[2 4]]
5. Determinant
print([Link](A))
Output:
-2.0000000000000004
6. Inverse
print([Link](A))
Output:
[[-2. 1. ]
[ 1.5 -0.5]]
7. Rank of a Matrix
print([Link].matrix_rank(A))
Output:
8. Trace
(Sum of diagonal elements).
print([Link](A)) # 1 + 4 = 5
9. Norms
Length (magnitude) of a matrix.
print([Link](A))
Output:
5.477225575051661
Output (approx):
1. Sum
Syntax:
[Link](arr, axis=None)
Example:
import numpy as np
arr = [Link]([[1, 2, 3],
[4, 5, 6]])
3. Mean (Average)
Syntax:
[Link](arr, axis=None)
Example:
print([Link](arr)) # Mean of all
print([Link](arr, axis=0)) # Column mean
print([Link](arr, axis=1)) # Row mean
Output:
3.5
[2.5 3.5 4.5]
[2. 5.]
4. Median
Syntax:
[Link](arr, axis=None)
Example:
print([Link](arr)) # Median of all
print([Link](arr, axis=0))# Column median
Output:
3.5
[2.5 3.5 4.5]
Summary
Function Description Example
[Link] Sum of [Link](arr)
elements
Creation Operations
Create arrays in different ways:
import numpy as np
[Link]([1,2,3]) # From list
[Link]((2,3)) # Array of zeros
[Link]((2,3)) # Array of ones
[Link]((2,3)) # Empty (garbage
values)
[Link](0,10,2) # Range
[Link](0,1,5) # Evenly spaced
values
[Link](1,10,(2,3)) # Random integers
2. Inspection Operations
Check properties of arrays:
arr = [Link]([[1,2,3],[4,5,6]])
print([Link]) # (2,3) → 2 rows, 3 cols
print([Link]) # 2 → dimensions
print([Link]) # 6 → total elements
print([Link]) # int64 → type
print([Link]) # 8 → bytes per element
print([Link]) # 48 → total memory
4. Iteration
for row in arr2d:
print(row)
for x in [Link](arr2d):
print(x)
5. Shape Manipulation
arr = [Link](6) # [0 1 2 3 4 5]
print([Link](2,3)) # Change shape
print([Link]()) # Flatten to 1D
print(arr.T) # Transpose
print(arr[:, [Link]]) # Add new axis (column
vector)
6. Copying
a = [Link]([1,2,3])
b = a # Assignment (no copy)
c = [Link]() # View (shallow copy)
d = [Link]() # Deep copy
7. Arithmetic Operations
Element-wise:
x = [Link]([1,2,3])
y = [Link]([4,5,6])
print(x + y) # [5 7 9]
print(x - y) # [-3 -3 -3]
print(x * y) # [ 4 10 18]
print(x / y) # [0.25 0.4 0.5]
print(x ** 2) # [1 4 9]
With scalars:
print(x + 5) # [6 7 8]
print(x * 2) # [2 4 6]
8. Comparison Operations
print(x > 2) # [False False True]
print(x == 2) # [False True False]
print([Link](x > 0)) # True
print([Link](x > 2)) # True
9. Logical Operations
a = [Link]([True, False, True])
b = [Link]([False, False, True])
Data Type Can store mixed Must store same type Must store same type
types (int, str, (defined by typecode) (dtype)
float, etc.)
Memory Usage High (stores Low (compact C-style Lowest & efficient
references + memory) (contiguous block in C)
objects)
Speed Slower (dynamic Faster than list (typed Fastest (vectorized ops in
typing overhead) data) C)
Size flexibility Dynamic, can Dynamic, but elements Fixed dtype, resizing costly
grow/shrink must match typecode