0% found this document useful (0 votes)
3 views37 pages

Numpy Full Tutorial

NumPy is an open-source Python library essential for scientific computing, providing a multidimensional array object that allows for efficient mathematical operations on large datasets. The tutorial covers installation, importing, and the creation of 1D, 2D, and 3D arrays, along with indexing, slicing, and array attributes. It also explains the differences between NumPy arrays and Python lists, as well as various methods for creating arrays such as zeros, ones, and ranges.

Uploaded by

alaaatefmuh180
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views37 pages

Numpy Full Tutorial

NumPy is an open-source Python library essential for scientific computing, providing a multidimensional array object that allows for efficient mathematical operations on large datasets. The tutorial covers installation, importing, and the creation of 1D, 2D, and 3D arrays, along with indexing, slicing, and array attributes. It also explains the differences between NumPy arrays and Python lists, as well as various methods for creating arrays such as zeros, ones, and ranges.

Uploaded by

alaaatefmuh180
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Numpy Full Tutorial.

md 8/23/2025

NumPy (Numerical Python)


What is NumPy?

NumPy is an open source Python library that’s widely used in science and engineering.
It is the fundamental package for scientific computing in Python.
It provides a multidimensional array object.
NumPy arrays facilitate advanced mathematical and other types of operations on large numbers of
data. Typically, such operations are executed more efficiently and with less code than is possible using
Python’s built-in sequences.

[Link]

Installing NumPy

!pip install numpy

Requirement already satisfied: numpy in e:\anaconda\lib\site-packages


(1.24.3)Note: you may need to restart the kernel to use updated packages.

[notice] A new release of pip is available: 24.3.1 -> 25.0.1


[notice] To update, run: [Link] -m pip install --upgrade pip

Importing NumPy

import numpy as np

NumPy Arrays (ndarrays)


NumPy Arrays Restrictions

All elements of the array must be of the same type of data.


Once created, the total size of the array can’t change.
The shape must be “rectangular”, not “jagged” which means that each row of a two-dimensional array
must have the same number of columns.

1 / 37
Numpy Full [Link] 8/23/2025

1D-Array
[Link]

One way to initialize an array is using a Python sequence, such as a list.


array(): Function used to create ndarray objects

# Creating a 1D-array
a = [Link]([5, 7, 2, 3, 8])
a

array([5, 7, 2, 3, 8])

Checking the type of Numpy array (data type of the elements inside the array):
ndarray: Core NumPy class for N-dimensional arrays

type(a)

[Link]

Difference between an array and a list of lists:


is that an element of the array can be accessed by specifying the index along each axis within a single
set of square brackets, separated by commas.

Indexing and Slicing 1D-Array


1) Indexing:

we can access an individual element of this array as we would access an element in the original list:
using the integer index of the element within square brackets.
NumPy arrays are “0-indexed”: the first element of the array is accessed using index 0, not 1.

2) Slicing:

process of extracting a subset of elements from an array using a range of indices.

Indexing:

2 / 37
Numpy Full [Link] 8/23/2025

a[0]

a[-1] # acessing the last element of array

Like the original Lists, arrays are mutable.

a[0] = 10
a

array([10, 7, 2, 3, 8])

Slicing:
Using: array_name[start:stop:step]
Note:
step may not be specified

a[:3] # slicing from index 0 to index 2 (excluding index 3)

array([10, 7, 2])

a[:] # slicing all the array (returning all array elements)

array([10, 7, 2, 3, 8])

a[::2] # specifiying step to be 2

3 / 37
Numpy Full [Link] 8/23/2025

array([10, 2, 8])

Major Difference between Lists and NumPy arrays:


List: slice indexing copies the elements into a new list.
Array: slicing an array returns a view ( a reference object that refers to the data in the original array).
The original array can be mutated using the view.

# Slicing and Copying a Python List


lst = [1, 2, 3, 4, 5]
sub_lst = lst[1:4]
sub_lst[0] = 99

lst # [1, 2, 3, 4, 5] → Original is unchanged

[1, 2, 3, 4, 5]

# Slicing and Copying an Array


arr = [Link]([1, 2, 3, 4, 5])
view = arr[1:4]
view[0] = 99

print(arr) # [1, 99, 3, 4, 5] → Original is changed

[ 1 99 3 4 5]

Conclusion:
Slicing a Python list ➝ returns a copy.
Slicing a NumPy array ➝ returns a view.

2D-Array:
A two-dimensional array would be like a table:

[Link]

Two and higher-dimensional arrays can be initialized from nested Python sequences:

4 / 37
Numpy Full [Link] 8/23/2025

b = [Link]([[1, 5, 2, 0], [8, 3, 6, 1], [1, 7, 2, 9]])


b

array([[1, 5, 2, 0],
[8, 3, 6, 1],
[1, 7, 2, 9]])

Indexing and Slicing 2D-Arrays


Indexing:

Accessing a single element:

b[1][3] # 1 → element in 2nd row, 4th column

# Another way
b[1,3] # 1 → element in 2nd row, 4th column

b[0,2] # 2 → element in 1st row, 3rd column

Slicing:

Slicing 2D-Array:

# Slicing Rows and Columns


b[0:2, 1:3] #slicing 2nd and 3rd columns from 1st and 2nd rows

5 / 37
Numpy Full [Link] 8/23/2025

array([[5, 2],
[3, 6]])

# Slicing all Rows and a specific Column


b[:, 1]

array([5, 3, 7])

# Slicing a specific Row and all Columns


b[2, :]

array([1, 7, 2, 9])

# Slicing Last Two Columns from the Last Row


b[-1:, -2:]

array([[2, 9]])

3D-Array:
Array that has three dimensions (or axes).

It can be visualized as a collection of 2D matrices stacked on top of each other.

In the context of machine learning and deep learning, a 3D array is also known as a 3rd-order tensor
or simply a tensor of rank 3.

A tensor is a multi-dimensional array used to store and manipulate numerical data. It is a


generalization of scalars, vectors, and matrices to higher dimensions.

A three-dimensional array would be like a set of tables:

[Link]

6 / 37
Numpy Full [Link] 8/23/2025

c = [Link]([
[[5, 16, 0], [4, 5, 6], [8, 1, 9]], # First 3x3 matrix
[[10, 23, 15], [2, 14, 15], [1, 22, 14]], # Second 3x3 matrix
[[4, 10, 6], [17, 0, 12], [5, 56, 13]] # Third 3x3 matrix
])
c

array([[[ 5, 16, 0],


[ 4, 5, 6],
[ 8, 1, 9]],

[[10, 23, 15],


[ 2, 14, 15],
[ 1, 22, 14]],

[[ 4, 10, 6],
[17, 0, 12],
[ 5, 56, 13]]])

Indexing and Slicing 3D-Arrays


Indexing:

Indexing a Single Element:

array_name [layer_index][row_index][column_index]

c[0,1,2] # Accessing element in 3rd column of 2nd row in 1st Layer, Output: one
number (Scalar)

Note: Scalar is a 0-D Array.

# Another way
c[0][1][2] # Accessing element in 3rd column of 2nd row in 1st Layer

7 / 37
Numpy Full [Link] 8/23/2025

Indexing an Entire Matrix (Layer):

c[1] # Accessing the 2nd Layer (Matrix)

array([[10, 23, 15],


[ 2, 14, 15],
[ 1, 22, 14]])

Indexing a Row from a Specific Layer:

c[1,2] # Accessing 3rd row from 2nd Layer , Output: 1D-array

array([ 1, 22, 14])

Slicing:

Indexing a Column Across All Layers:

c[:,:,1] # Output: 2D-Array

array([[16, 5, 1],
[23, 14, 22],
[10, 0, 56]])

Slicing a Sub-Matrix:

c[0, 0:2, 0:2] # getting the 1st and 2nd rows and cols from the First Layer

array([[ 5, 16],
[ 4, 5]])

Array Attributes
ndim: Number of dimensions of array.

8 / 37
Numpy Full [Link] 8/23/2025

shape: Tuple of non-negative integers that specify the number of elements along each dimension.
size: Total number of array elements.
dtype: Data type of the array elements.
itemsize: Size (in bytes) of each element.
nbytes : Total memory consumed (in bytes),
nbytes = Total [Link] elements * size of element in array.

print(a)

[10 7 2 3 8]

[Link] # 1 refer to 1D-array

[Link] # 5 refer to 5 elements in array

(5,)

[Link] # returns total number of elements

len([Link]) == [Link]

True

Note:
So for any NumPy array: len([Link]) is always equal to [Link].

9 / 37
Numpy Full [Link] 8/23/2025

[Link]

dtype('int32')

Remember:
All elements of numpy array must be of the same data type.

Default Data Type of Numpy Array


The default data type of a NumPy array depends on the input values when you create the array.

int_arr = [Link]([2, 4, 5, 9])


int_arr.dtype

dtype('int32')

float_arr = [Link]([2.1, 6.2, 3.89, 22.1])


float_arr.dtype

dtype('float64')

str_arr = [Link](["Alaa", "Atef", "IEEE", "AUSC"])


str_arr.dtype # (<U) ==> Unicode string

dtype('<U4')

Mixed Arrays:
NumPy will automatically upcast the elements to a common data type that can represent all the
values. This process is called Type Promotion.

arr_1 = [Link]([1, 2.5, 4])


arr_1.dtype # int + float = float

10 / 37
Numpy Full [Link] 8/23/2025

dtype('float64')

arr_2 = [Link](["ML", 2, 6])


arr_2.dtype # int + string = string

dtype('<U11')

arr_3 = [Link]([True, False, 3.14])


arr_3.dtype # float + boolean = float

dtype('float64')

arr_4 = [Link]([False, 10])


arr_4.dtype # int + boolean = int

dtype('int32')

print(b)

[[1 5 2 0]
[8 3 6 1]
[1 7 2 9]]

[Link] # b is 2D-Array

11 / 37
Numpy Full [Link] 8/23/2025

[Link] # shape: ([Link] rows , [Link] cols)

(3, 4)

[Link] # (Total Elements) = [Link] rows X [Link] cols

12

import math # math module for calculations


# Just for checking if the product of [Link] cols and [Link] rows the same as the
size (total elemets) of the array
[Link] == [Link]([Link])

True

[Link]

dtype('int32')

[Link]

[Link] # nbytes = 12 elements X 4 (size of an element) = 48 bytes

48

12 / 37
Numpy Full [Link] 8/23/2025

Creating a Basic Array


[Link](): Creates an array filled with zeros.

[Link](): Creates an array filled with ones.

[Link](): Creates an array without initializing entries (values are random values)

[Link](): Creates values from start to stop (exclusive), spaced by step.

[Link](): Creates num evenly spaced values from start to stop (inclusive).

[Link](shape):

[Link](3)

array([0., 0., 0.])

[Link]((2,3))

array([[0., 0., 0.],


[0., 0., 0.]])

# Creating a zeros array with the same shape as b array


[Link]([Link]) # Remember: Shape of b Array ==> 3X4

array([[0., 0., 0., 0.],


[0., 0., 0., 0.],
[0., 0., 0., 0.]])

[Link](shape):

[Link]((3,3))

array([[1., 1., 1.],


[1., 1., 1.],
13 / 37
Numpy Full [Link] 8/23/2025

[1., 1., 1.]])

[Link](shape):

# Create an empty array with 2 elements


[Link](2)

array([0., 0.])

[Link]((2,3))

array([[0., 0., 0.],


[0., 0., 0.]])

Important Notes:

The function empty creates an array whose initial content is random and depends on the state
of the memory.
The reason to use empty() over zeros() and ones() is speed.

[Link](range_of_elements):

[Link](4) # Creating an array with a range of elements from 0 to 4(exclusive)

array([0, 1, 2, 3])

[Link](3, 10, 2) # Creating an array with range of elements from 3 to


10(exclusive) by moving 2 steps

array([3, 5, 7, 9])

[Link](start, stop, num):


Creates an array with values that are spaced linearly in a specified interval.

14 / 37
Numpy Full [Link] 8/23/2025

[Link](0, 10, num=5) # Start=0, stop=10(Inclusive) , num=5 (specifying 5


evenly spaced numbers)

array([ 0. , 2.5, 5. , 7.5, 10. ])

Specifying the Data Type


The default data type is floating point (np.float64).

[Link](2)

array([1., 1.])

x = [Link](2, dtype=np.int64)
x

array([1, 1], dtype=int64)

Adding, Removing and Sorting Elements


Sorting Array using:

1. [Link](): Returns a sorted copy of the array.

arr = [Link]([2, 5, 3, 7, 4 ,1 ,8, -1])


sort_arr = [Link](arr)
print("Sorted Array:", sort_arr)
print("Un-sorted Array:", arr) # original array remains the same

Sorted Array: [-1 1 2 3 4 5 7 8]


Un-sorted Array: [ 2 5 3 7 4 1 8 -1]

2. [Link]():

15 / 37
Numpy Full [Link] 8/23/2025

Indirect sort along a specified axis.


Returns the indices that would sort the array.

arr = [Link]([10, 30, 20])


idx = [Link](arr)

print(idx) # [0 2 1] → arr[0] < arr[2] < arr[1]


print("Final Sorted Array:", arr[idx]) # [10 20 30]

[0 2 1]
Final Sorted Array: [10 20 30]

3. [Link]():

Indirect stable sort on multiple keys (from last to first key).

names = [Link](['Alaa', 'Mirna', 'Youness', 'Sara'])


grades = [Link]([99, 98, 85, 90])

# Sort by name first, then by grade


sorted_idx = [Link]((grades, names))

print(sorted_idx) # [1 3 2 0]
print(names[sorted_idx]) # ['Jane' 'Jane' 'Tom' 'Tom']
print(grades[sorted_idx]) # [99 9 85 90]

[0 1 3 2]
['Alaa' 'Mirna' 'Sara' 'Youness']
[99 98 90 85]

4. [Link]():

Finds the index where elements should be inserted to maintain order in a sorted array.

arr = [Link]([10, 20, 30, 40])


indices = [Link](arr, [25, 35])

print(indices) # [2 3] → 25 goes before 30, 35 before 40

[2 3]

16 / 37
Numpy Full [Link] 8/23/2025

5. [Link]():

Rearranges the array so that the element that would be in the specified position (specified index) if
the array was fully sorted, is placed in that position.

The numbers before it are smaller or equal, the numbers after it are larger or [Link] it does not sort
the entire array.

arr = [Link]([7, 2, 1, 9, 6])


part = [Link](arr, 2)

print(part) # Resulted array: [1 2 6 9 7]

[1 2 6 9 7]

Concatenating Arrays
Joining two or more arrays along an existing axis (does not add a new dimension).

Arrays must have the same shape except along the axis you concatenate on.

Conatenating 1D Arrays:

x = [Link]([1, 2, 3, 4])
y = [Link]([5, 6, 7, 8])

[Link]((x, y))

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

Concatenating 2D Arrays (Axis Matters):


Notes:

The shapes must match except for the axis you're concatenating on.

For axis=0 (row-wise): number of columns must match.

For axis=1 (column-wise): number of rows must match.

m = [Link]([[1, 2], [3, 4]])


n = [Link]([[5, 6]])

17 / 37
Numpy Full [Link] 8/23/2025

[Link]((m, n), axis=0) # Concatenate along axis 0 (row-wise)

array([[1, 2],
[3, 4],
[5, 6]])

# Concatenate along axis 1 (add more columns)


a = [Link]([[1, 2], [3, 4]])
b = [Link]([[5], [6]])

[Link]((a, b), axis=1) # Concatenate along axis 1 (column-wise)

array([[1, 2, 5],
[3, 4, 6]])

Stacking Arrays
Joining arrays along a new axis (adds a new dimension).

All input arrays must have the same shape.

s1 = [Link]([[1, 1],
[2, 2]])

s2 = [Link]([[3, 3],
[4, 4]])

print("Shape of s1 or s2:", [Link])


# Checking the shape of both arrays (Must be checked)
print([Link] == [Link])

Shape of s1 or s2: (2, 2)


True

Stacking 2 Arrays Vertically (Row-wise) using [Link]():

arrs_vert = [Link]((s1, s2))


arrs_vert
18 / 37
Numpy Full [Link] 8/23/2025

array([[1, 1],
[2, 2],
[3, 3],
[4, 4]])

print("New Shape:", arrs_vert.shape)

New Shape: (4, 2)

Stacking 2 Arrays Horizontally (Column-wise) using [Link]():

arrs_horiz = [Link]((s1, s2))


print(arrs_horiz)

[[1 1 3 3]
[2 2 4 4]]

3D Stacking (Depth-wise Stack) using [Link]():

d1 = [Link]([[1, 2], [3, 4]])


d2 = [Link]([[5, 6], [7, 8]])

d_stacked = [Link]((d1, d2))


print("Resulted Stacked Array:\n", d_stacked)

Resulted Stacked Array:


[[[1 5]
[2 6]]

[[3 7]
[4 8]]]

d_stacked.ndim # resulted dimensions after applying 3D Stacking

19 / 37
Numpy Full [Link] 8/23/2025

Splitting Arrays
The opposite of concatenating or stacking.

Splitting an array into several smaller arrays.

[Link]():

Splits an array into equal parts along a specified axis.

You must provide a number of splits that divides the array evenly.

sp1 = [Link]([1, 2, 3, 4, 5, 6])


[Link](sp1, 3) # splitting array into 3 equal parts

[array([1, 2]), array([3, 4]), array([5, 6])]

np.array_split():

More flexible than split().

Allows splitting even if the array cannot be divided equally.

sp2 = [Link]([1, 2, 3, 4, 5])


np.array_split(sp2, 3) # Observed: last array containing only one element.

[array([1, 2]), array([3, 4]), array([5])]

Horizontal split using [Link]():

Splits columns (works on 2D arrays)

Equivalent to [Link](axis=1)

sp3 = [Link]([[1, 2, 3], [4, 5, 6]])


[Link](sp3, 3) # splitting array horizontally into 3 equal parts

20 / 37
Numpy Full [Link] 8/23/2025

[array([[1],
[4]]),
array([[2],
[5]]),
array([[3],
[6]])]

Vertical Split using [Link]():

Splits rows (works on 2D arrays)

Equivalent to [Link](axis=0)

[Link](sp3, 2) # Splitting array vertically into 2 equal parts

[array([[1, 2, 3]]), array([[4, 5, 6]])]

Depth Split using [Link]():


Splits along the depth (3rd) axis in 3D arrays.

sp4 = [Link]([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])


[Link](sp4, 2)

[array([[[1],
[3]],

[[5],
[7]]]),
array([[[2],
[4]],

[[6],
[8]]])]

Reshaping Arrays
Reshaping means changing the shape (dimensions) of a NumPy array without changing its data.
When you use the reshape method, the array you want to produce needs to have the same number of
elements as the original array.

21 / 37
Numpy Full [Link] 8/23/2025

If you start with an array with 12 elements, you’ll need to make sure that your new array also has a total
of 12 elements.

arr = [Link](6)
resh_arr = [Link](3, 2)

print("Original Array:", arr)


print("Reshaped Array:", resh_arr)

Original Array: [0 1 2 3 4 5]
Reshaped Array: [[0 1]
[2 3]
[4 5]]

Default Reshaping
NumPy calculates the appropriate dimension that fits the data by passing the number of rows you want
and then -1.

reshaped_2rows = [Link](2, -1) # NumPy figures out the number of columns

print("Reshaped Array:", reshaped_2rows)

Reshaped Array: [[0 1 2]


[3 4 5]]

reshaped_3rows = [Link](3, -1) # NumPy figures out the number of columns

print("Reshaped Array:", reshaped_3rows)

Reshaped Array: [[0 1]


[2 3]
[4 5]]

Transposing Arrays

22 / 37
Numpy Full [Link] 8/23/2025

Reversing or changing the axes of an array according to the values you specify.
Using:
array_name.transpose()
array_name.T

arr = [Link](6).reshape((2, 3))


arr

array([[0, 1, 2],
[3, 4, 5]])

print("Shape of Oiginal Array:", [Link])

Shape of Oiginal Array: (2, 3)

transposed_arr = [Link]()

print("Transposed Array:", transposed_arr)


print("Shape of Transposed Array:", transposed_arr.shape)

Transposed Array: [[0 3]


[1 4]
[2 5]]
Shape of Transposed Array: (3, 2)

# Another way
arr.T

array([[0, 3],
[1, 4],
[2, 5]])

Reversing Arrays
23 / 37
Numpy Full [Link] 8/23/2025

[Link](): function allows you to flip, or reverse, the contents of an array along an axis.

Note:

When using [Link](), specify the array you would like to reverse and the axis. If you don’t specify
the axis, NumPy will reverse the contents along all of the axes of your input array.

Reversing 1D Array:

arr_1d = [Link]([1, 2, 3, 4, 5, 6, 7, 8])


print("Array Before Reversing:", arr_1d)

# Reversing Array
reversed_arr = [Link](arr_1d)
print("Reversed 1D Array:", reversed_arr)

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


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

Reversing 2D Array:

Reversing the content in all of the rows and all of the columns.

arr_2d = [Link]([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])


print("Array Before Reversing:\n", arr_2d)

# Reversing Array
reversed_arr_2d = [Link](arr_2d)
print("Reversed 2D Array \n", reversed_arr_2d)

Array Before Reversing:


[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
Reversed 2D Array
[[12 11 10 9]
[ 8 7 6 5]
[ 4 3 2 1]]

Reversing only the Rows.

reversed_arr_rows = [Link](arr_2d, axis=0) # axis=0 refers to reversing the rows


print(reversed_arr_rows)

24 / 37
Numpy Full [Link] 8/23/2025

[[ 9 10 11 12]
[ 5 6 7 8]
[ 1 2 3 4]]

Reversing only the Columns.

reversed_arr_cols = [Link](arr_2d, axis=1) # axis=0 refers to reversing the cols


print(reversed_arr_cols)

[[ 4 3 2 1]
[ 8 7 6 5]
[12 11 10 9]]

Reverse the contents of a Specific Row.

arr_2d[1] = [Link](arr_2d[1])
print(arr_2d)

[[ 1 2 3 4]
[ 8 7 6 5]
[ 9 10 11 12]]

Reverse the contents of a Specific Column.

arr_2d[:,1] = [Link](arr_2d[:,1])
print(arr_2d)

[[ 1 10 3 4]
[ 8 7 6 5]
[ 9 2 11 12]]

Flattening Multidimensional Arrays


Converting a multi-dimensional array (like 2D or 3D) into a 1D array (a single continuous list of
elements).
25 / 37
Numpy Full [Link] 8/23/2025

Reasons for Flattening Arrays:

To prepare data for machine learning models that expect 1D input (Ex: logistic regression).
To pass image pixel data (Ex: 2D grayscale images) into a model as a flat vector.

2 Functions:

array_name.flatten(): Created a new array which is a reference to the parrent array (View).
Any changes to the new array will affect the parent array as well.
array_name.ravel(): Ddoes not create a copy, it’s memory efficient.

Using flatten() function:

x = [Link]([[1 , 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])


print(x)
print("Shape of Array:", [Link])
print("Dim of Array:", [Link])

[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]
Shape of Array: (3, 4)
Dim of Array: 2

[Link]()

array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])

When you use flatten, changes to your new array won’t change the parent array.

a1 = [Link]()
a1[0] = 99
print("New Array:", a1)
print("The original Array:\n", x) # Original array

New Array: [99 2 3 4 5 6 7 8 9 10 11 12]


The original Array:
[[ 1 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]

26 / 37
Numpy Full [Link] 8/23/2025

Using ravel() function:


Changes you make to the new array will affect the parent array.

a2 = [Link]()
a2[0] = 98
print("New Array:", a2)
print("Original Array:\n", x)

New Array: [98 2 3 4 5 6 7 8 9 10 11 12]


Original Array:
[[98 2 3 4]
[ 5 6 7 8]
[ 9 10 11 12]]

Basic Array Operations


Addition
Subtraction
Multiplication
Division

[Link] [Link]

# Creating Arrays
data = [Link]([1, 2])
ones = [Link](2, dtype=int)
print(ones)

[1 1]

Adding Arrays together:

[Link]

result_arr = data + ones


print("Result:", result_arr)

Result: [2 3]

27 / 37
Numpy Full [Link] 8/23/2025

# Subtraction
data - ones

array([0, 1])

# Multiplication
data * data

array([1, 4])

# Division
data / data

array([1., 1.])

[Link]

Calculating the sum of all elements in an array using sum():

c1 = [Link]([1, 2, 3, 4])
print("Sum of all elements:", [Link]())

Sum of all elements: 10

Adding Rows or Cols in a 2D array (axis argument must be specified)

c2 = [Link]([[1, 1], [2, 2]])


print(c2)

sum_c2 = [Link](axis=0) # axis=0 (summing over axis of rows)


print(sum_c2)

28 / 37
Numpy Full [Link] 8/23/2025

[[1 1]
[2 2]]
[3 3]

[Link](axis=1) # axis=1 (summing over axis of cols)

array([2, 4])

Aggregation Functions:
Used to summarize data.
[Link](): Total sum of elements
[Link](): Arithmetic mean
[Link](): Median (middle value)
[Link](): Standard deviation
[Link](): Variance
[Link](): Minimum value
[Link](): Maximum value
[Link](): Index of max element
[Link](): Index of min element
[Link](): Cumulative sum
[Link](): Cumulative product

data = [Link]([1, 2, 3])

print("Maximum Value:", [Link]())


print("Minimum Value:", [Link]())
print("Sum of array elements:", [Link]())

Maximum Value: 3
Minimum Value: 1
Sum of array elements: 6

data_2d = [Link]([
[2, 4, 5],
[9, 14, 0],
[8, 9, 15]
])
29 / 37
Numpy Full [Link] 8/23/2025

You can specify on which axis you want the aggregation function to be computed.

data_2d.min(axis=0) # taking each minimum value across Cols

array([2, 4, 0])

data_2d.max(axis=1) # taking each maximum value across Rows

array([ 5, 14, 15])

data_2d.mean() # mean of all elements in array

7.333333333333333

# Specifying axis
data_2d.mean(axis=0) # taking the mean across Cols

array([6.33333333, 9. , 6.66666667])

# Specifying axis
data_2d.mean(axis=1) # taking the mean across Rows

array([ 3.66666667, 7.66666667, 10.66666667])

[Link](data_2d) # Middle value

30 / 37
Numpy Full [Link] 8/23/2025

8.0

# Calculating standard deviation of data


[Link](data_2d)

4.8074017006186525

# Calculating Variance (variation) fo data


[Link](data_2d)

23.11111111111111

[Link](data_2d) # returns index of max value which is: index(8)

[Link](data_2d) # returns index of min value which is: index(5)

# Cumulative Summation
[Link](data_2d) # taking each element and adding it to the previous one and so
one

array([ 2, 6, 11, 20, 34, 34, 42, 51, 66])

31 / 37
Numpy Full [Link] 8/23/2025

# Cumulative Product
[Link](data_2d) # taking each element and multiplying it by the previous one
and so one

array([ 2, 8, 40, 360, 5040, 0, 0, 0, 0])

All the above functions uses Aggregation along Axes just by specifying the axis (axis=0 or axis=1)

BroadCasting Arrays
Powerful feature in NumPy that allows arithmetic operations on arrays of different shapes(without
explicitly replicating data).

It automatically expands the smaller array across the larger one so their shapes become compatible for
element-wise operations.

Important Rule:

The dimensions of your array must be compatible, for example, when the dimensions of both
arrays are equal or when one of them is 1. If the dimensions are not compatible, you will get a
ValueError.

Array * Scalar:

[Link]

data = [Link]([1, 2])


result = data * 1.6
print("Resulted Array:", result)

Resulted Array: [1.6 3.2]

NumPy broadcasts the scalar 1.6 to match the shape of data → [1.6, 1.6].

Note:

NumPy understands that the multiplication should happen with each cell (which is called
Broadcasting)

2D and 1D Arrays:

d1 = [Link]([[1, 2, 3],
[4, 5, 6]])
32 / 37
Numpy Full [Link] 8/23/2025

d2 = [Link]([10, 20, 30])

print(d1 + d2) # d2 is broadcast across each row of d1

[[11 22 33]
[14 25 36]]

Example of Incompatible Shapes:

d3 = [Link]([[1, 2, 3],
[4, 5, 6]])

d4 = [Link]([1, 2]) # Not compatible

# Check the Error


# ValueError: operands could not be broadcast together
print(d3 + d4)

---------------------------------------------------------------------------

ValueError Traceback (most recent call last)

Cell In[225], line 8


4 d4 = [Link]([1, 2]) # Not compatible
6 # This will raise an error
7 # ValueError: operands could not be broadcast together
----> 8 print(d3 + d4)

ValueError: operands could not be broadcast together with shapes (2,3) (2,)

Comparing Performance: NumPy Arrays vs Python Lists


NumPy performs operations using compiled C code under the hood, making it much faster and more
memory efficient.

Python lists require looping through elements manually, which is slower, especially for large datasets.

This is why NumPy is preferred in data science, ML, and scientific computing.

import time

33 / 37
Numpy Full [Link] 8/23/2025

# Defining the size of the dataset (1 million elements)


size = 10 ** 6

# Creating a NumPy array and a Python list


num_arr = [Link](size)
py_list = list(range(size))

#NumPy: Vectorized element-wise addition


start_time = [Link]()
num_result = num_arr + num_arr # Efficient element-wise addition
numpy_time = [Link]() - start_time

# Python List: Attempting similar operation


# Python lists do not support element-wise addition directly.
start_time = [Link]()
py_result = [x + y for x, y in zip(py_list, py_list)] # Manual loop-based
addition
python_time = [Link]() - start_time

print("NumPy Array Addition Time:", numpy_time)


print("Python List Addition Time:", python_time)

NumPy Array Addition Time: 20.871354341506958


Python List Addition Time: 255.5365285873413

Accessing DocString
Every object contains the reference to a string, which is known as the docstring.

Docstring contains a quick and concise summary of the object and how to use it.

It will act as documentation for others (or for you later) to understand what the script is for
and how it works.

Accessing this infromation using help() function

help(max) # finding all information about function max()

Help on built-in function max in module builtins:

max(...)
max(iterable, *[, default=obj, key=func]) -> value
max(arg1, arg2, *args, *[, key=func]) -> value

34 / 37
Numpy Full [Link] 8/23/2025

With a single iterable argument, return its biggest item. The


default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the largest argument.

# Another way for accessing more information


max?

Useful Information about a Specific Array:


using ? Character

arr_1D = [Link]([10, 12, 15, 21, 29])

Cell Below shows:


Details about arr_1D itself followed by the docstring of ndarray of which arr_1D array is an
instance.

arr_1D?

Defining your function with Docstring then obtaining information about it:

# Adding DocString to your function


def operat(x1, x2):
"""
Adds two numbers and increments the result by 2.

Parameters:
x1 (int or float): The first number
x2 (int or float): The second number

Returns:
int or float: The result of (x1 + x2 + 2).
"""
return x1 + x2 + 2

operat?

Saving and Loading NumPy Objects

35 / 37
Numpy Full [Link] 8/23/2025

At some point, you will want to save your arrays to disk and load them back without having to re-run
the code.

load() and save() functions can handle NumPy binary files with a .npy file extension, and a savez
function that handles NumPy files with a .npz file extension.

The .npy and .npz files store data, shape, dtype, and other information required to reconstruct the
ndarray in a way that allows the array to be correctly retrieved, even when the file is on another
machine with different architecture.

If you want to store a single ndarray object, store it as a .npy file using [Link]().

If you want to store more than one ndarray object in a single file, save it as a .npz file using
[Link]().

X = [Link]([1, 2, 3, 4, 5, 6])

Saving it as “[Link]” using [Link]("filename", array_name)

[Link]('one_ndarray', X)

Loading the file to reconstruct X array:

X_recons = [Link]('one_ndarray.npy')
X_recons

array([1, 2, 3, 4, 5, 6])

Saving a NumPy array as a plain text file like a .csv or .txt file with [Link]("[Link]",
array_name).

csv_arr = [Link]([1, 2, 3, 4, 5, 6, 7, 8])

#Saving defined array as .csv file


[Link]('array_csv_file.csv', csv_arr)

Then, You can quickly and easily load your saved text file using loadtxt():

[Link]('array_csv_file.csv')
36 / 37
Numpy Full [Link] 8/23/2025

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

37 / 37

You might also like