What is Numpy?

  • Numpy stands for numerical python
  • It is a Python package/library for numerical calculations, broadcasting functions & processing for multi-dimensional & single dimensional array elements
  • Travis Oliphant created the NumPy package in 2005
  • It is very fast as it is written in C programming language
  • It is built on linear algebra. It is about matrics & vectors. Performs mathematical calculations on them
  • It is convenient for matrix multiplication & data reshaping
  • It requires homogeneous data values. For example: It can contain either integer or float numbers but not both at the same time

The key concept in Numpy is the Numpy Array data type. A Numpy array may have one or more dimensions:

  • One-dimensional arrays(1D) represent vectors.
  • Two-dimensional arrays(2D) represent matrices.
  • Higher dimensional arrays represent tensors.

Arrays are indexed just like Sequences, starting with zero.

Install NumPy:

  • To install NumPy, need to use the following command
!pip install numpy

Import Numpy:

import numpy  #or below with alias
import numpy as np
  • NumPy can be used directly in coding. But normal practice is to use np.
  • np is an alias commonly used. Anything can be used instead of this but other code readers can understand easily my code if I use np.

NumPy Arrays:

Ndarray:

  • ndarray is the n-dimensional array object defined in the NumPy which stores the collections of similar type of elements.
  • Numpy is used to work with arrays .
  • The array object in NumPy is called ndarray

Numpy is essentially of two types:

1. Vector:

    • A vector is a one-dimensional array of numbers. It can be represented as a column vector (vertical arrangement) or a row vector (horizontal arrangement).
    • Each element in a vector is identified by its position or index.
    • Vectors are commonly used to represent quantities such as velocity, force, or coordinates in space.
    • Examples:
      • Column vector: [1, 2, 3]
      • Row vector: [[1, 2, 3]] (in some contexts)

2. Matrix:

    • A matrix is a two-dimensional array of numbers arranged in rows and columns.
    • Each element in a matrix is identified by its row and column indices.
    • Matrices are used to represent data, transformations, or systems of linear equations.
    • Examples:

[1 2 3]

[4 5 6]

[7 8 9]

This is a 3×3 matrix with 3 rows and 3 columns.

Syntex & Parameter:

Syntex:

numpy.array(object,dtype=None, copy=True, order =None, subok=False,ndmin=0)

Parameter:

object-It represents the collection object. It can be a list, tuple, dictionary, set, etc.

dtype– We can change the data type of the array elements by changing this option to the specified type. The default is none.

copy-It is optional. By default, it is true which means the object is copied.

order-There can be 3 possible values assigned to this option. It can be C (column order), R (row order), or A (any)

subok– The returned array will be a base class array by default. We can change this to make the subclasses pass through by setting this option to true.

ndmin– It represents the minimum dimensions of the resultant array.

Creating NumPy Arrays:

Vectors:

# Create an empty array

emp_arr1 = np.array('')
print('emp_arr1',emp_arr1)

emp_arr2 = np.array([])
print('emp_arr2',emp_arr2)
Output:
emp_arr1 
emp_arr2 []
# Create array from list

my_list = [2,3,1,32,45,67,87,88,23]
list_arr= np.array([2,3,1,32,45,67,87,88,23])
list_arr
Output:
array([ 2,  3,  1, 32, 45, 67, 87, 88, 23])
# create list from array

list_arr.tolist() #or
list(list_arr)
Ouput:
[2, 3, 1, 32, 45, 67, 87, 88, 23]
#Check if it is list type 
type(list_arr.tolist())
Output:
list
# Create array from tuple
my_tup =(2,3,4,5,6,7,8)
list_arr= np.array(my_tup)
list_arr
Ouput:
array([2, 3, 4, 5, 6, 7, 8])
# Find type of variable

type(list_arr)
Output:
numpy.ndarray
# Find datatype

list_arr.dtype
Output:
dtype('int64')
# Find dimension in the array

list_arr.ndim
Output:
1
# Find size of array ( how many value in array)

list_arr.size
Output:
7
# Find shape of array

list_arr.shape
Output:
(7,)

Matrices/Matrix:

# 2 dimension array

my_matrix =[[1,2,3,4],[5,6,7,8],[1,3,5,7]]
my_matrix
Output:
[[1, 2, 3, 4], [5, 6, 7, 8], [1, 3, 5, 7]]
# Creating array

matrix_array=np.array(my_matrix)
matrix_array
Output:
array([[1, 2, 3, 4],
       [5, 6, 7, 8],
       [1, 3, 5, 7]])
# Find type of variable

type(matrix_array)
Output:
numpy.ndarray
# Find dimension of array

matrix_array.ndim
Output:
2
# Find size of array

matrix_array.size
Output:
12
# Find shape of array

matrix_array.shape
Output:
(3, 4)
# 3 dimensional array

my_matrix = [[[1,2,3],[2,3,4]],[[7,2,3],[8,3,4]]]
my_matrix
Output:
[[[1, 2, 3], [2, 3, 4]], [[7, 2, 3], [8, 3, 4]]]
# Creating array

matrix_array=np.array(my_matrix)
matrix_array
Ouput:
array([[[1, 2, 3],
        [2, 3, 4]],

       [[7, 2, 3],
        [8, 3, 4]]])
# Find type of variable

type(matrix_array)
Output:
numpy.ndarray
# Find dimension of array

matrix_array.ndim
Output:
3
# Find size of array

matrix_array.size
Output:
12
# Find shape of array

matrix_array.shape
Output:
(2, 2, 3)
# Find data type

matrix_array.dtype
Ouput:
dtype('int64')

Broadcasting:

  • The ability to access each & every element of an array is known as broadcasting
  • NumPy treats arrays with different shapes during arithmetic operations.
a = np.array([[1,2,3,4],[5,6,7,8],[9,8,7,6]])
a
Output:
array([[1, 2, 3, 4],
       [5, 6, 7, 8],
       [9, 8, 7, 6]])
b=(a*3).reshape((3,4))
b
Output:
array([[ 3,  6,  9, 12],
       [15, 18, 21, 24],
       [27, 24, 21, 18]])
c=a+b-10
c
Output:
array([[-6, -2,  2,  6],
       [10, 14, 18, 22],
       [26, 22, 18, 14]])
d=[[2,3,1,4]]
e=c*d
e
Output:

e=c*d
e
array([[-12,  -6,   2,  24],
       [ 20,  42,  18,  88],
       [ 52,  66,  18,  56]])

arange Function:

  • Creates an array of numbers with a specified range.
# use end only , default start with 0

np.arange(15)  # end excluded , difference between each value is one which is even
Output:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
# use start & end

np.arange(10,20)
Output:
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
# use start,end,step for jump

np.arange(10,20,2) # difference between each value is 2 which step number
Output:
array([10, 12, 14, 16, 18])
# use start,end, negative step number

np.arange(30,10,-2) # for this case start will be bigger than end number
Output:
array([30, 28, 26, 24, 22, 20, 18, 16, 14, 12])

reshape Function:

  • Reshape serves to change the existing shape of the array

  • Condition for reshaping: The total elements of both shapes must be same Example: One shape has 8 element, we can make 2d array for 4X2 or 2X4 but we can not make 3X4(12 elements required)

re_arr = np.array([30, 28, 26, 24, 22, 20, 18, 16, 14, 12])
re_arr
Output:
array([30, 28, 26, 24, 22, 20, 18, 16, 14, 12])
re_arr.shape
Output:
(10,)
re_arr.reshape((5,2))
Output:
array([[30, 28],
       [26, 24],
       [22, 20],
       [18, 16],
       [14, 12]])

linspace:

  • Return evenly spaced numbers over a specified interval
  • Default 50 observations within provided range
  • Both start & end included here
  • Return step computed by linspace
np.linspace(1,10)
Output:
array([ 1.        ,  1.18367347,  1.36734694,  1.55102041,  1.73469388,
        1.91836735,  2.10204082,  2.28571429,  2.46938776,  2.65306122,
        2.83673469,  3.02040816,  3.20408163,  3.3877551 ,  3.57142857,
        3.75510204,  3.93877551,  4.12244898,  4.30612245,  4.48979592,
        4.67346939,  4.85714286,  5.04081633,  5.2244898 ,  5.40816327,
        5.59183673,  5.7755102 ,  5.95918367,  6.14285714,  6.32653061,
        6.51020408,  6.69387755,  6.87755102,  7.06122449,  7.24489796,
        7.42857143,  7.6122449 ,  7.79591837,  7.97959184,  8.16326531,
        8.34693878,  8.53061224,  8.71428571,  8.89795918,  9.08163265,
        9.26530612,  9.44897959,  9.63265306,  9.81632653, 10.        ])
np.linspace(1,10,20)
Output:
array([ 1.        ,  1.47368421,  1.94736842,  2.42105263,  2.89473684,
        3.36842105,  3.84210526,  4.31578947,  4.78947368,  5.26315789,
        5.73684211,  6.21052632,  6.68421053,  7.15789474,  7.63157895,
        8.10526316,  8.57894737,  9.05263158,  9.52631579, 10.        ])
np.linspace(1,10,20,retstep=True) # retstep True gives difference value in output , default it is False
Output:
(array([ 1.        ,  1.47368421,  1.94736842,  2.42105263,  2.89473684,
         3.36842105,  3.84210526,  4.31578947,  4.78947368,  5.26315789,
         5.73684211,  6.21052632,  6.68421053,  7.15789474,  7.63157895,
         8.10526316,  8.57894737,  9.05263158,  9.52631579, 10.        ]),
 0.47368421052631576)

Zeros:

  • Create an array with zeros
# One dimensional
zero_arr_1d =np.zeros(6)
print("zero_arr_1d",zero_arr_1d)

# Two dimensional
zero_arr_2d =np.zeros((6,3))
print("zero_arr_2d",zero_arr_2d)
Output:
zero_arr_1d [0. 0. 0. 0. 0. 0.]
zero_arr_2d [[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

Ones:

  • Create an array with ones
one_arr= np.ones((3,6))
one_arr
Output:
array([[1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1.]])

Eye(Identify Matrix):

  • Create an array with eye
eye_arr_1d = np.eye(5)   # rows,columns , if columns none , default value will row number
print(" One dimensional :",eye_arr_1d)

eye_arr_2d = np.eye(2,3)
print(" Two dimensional :",eye_arr_2d)
Output:
 One dimensional : [[1. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0.]
 [0. 0. 1. 0. 0.]
 [0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 1.]]
 Two dimensional : [[1. 0. 0.]
 [0. 1. 0.]]

Diagonal Square matrix diag():

  • If you pass a vector to diag(), it creates a square matrix with the elements of the vector on its main diagonal and zeros elsewhere.
#use of diag() square matrix

arr =np.diag([1,2,3,4])
arr
Output:

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

Diagonal Square matrix with flattened input:

You can use np.diagflat() to create a diagonal matrix from the elements of a flattened array. This function provides a more direct way to create a diagonal matrix without needing to specify each diagonal element individually.

arr1 =np.diag([[1,2,3,4],[4,3,2,1],[4,3,2,1]])
print("arr1",arr1)

arr2 =np.diagflat([[1,2,3,4],[4,3,2,1],[4,3,2,1]])
print("arr2",arr2)
Output:



arr1 [1 3 2]
arr2 [[1 0 0 0 0 0 0 0 0 0 0 0]
 [0 2 0 0 0 0 0 0 0 0 0 0]
 [0 0 3 0 0 0 0 0 0 0 0 0]
 [0 0 0 4 0 0 0 0 0 0 0 0]
 [0 0 0 0 4 0 0 0 0 0 0 0]
 [0 0 0 0 0 3 0 0 0 0 0 0]
 [0 0 0 0 0 0 2 0 0 0 0 0]
 [0 0 0 0 0 0 0 1 0 0 0 0]
 [0 0 0 0 0 0 0 0 4 0 0 0]
 [0 0 0 0 0 0 0 0 0 3 0 0]
 [0 0 0 0 0 0 0 0 0 0 2 0]
 [0 0 0 0 0 0 0 0 0 0 0 1]]

For arr1= np.diag([[1,2,3,4],[4,3,2,1],[4,3,2,1]]), the function treats the given array as a matrix and extracts its diagonal elements. Since you provided a 2D array, it extracts the diagonal from the main diagonal of the array, which results in [1, 3, 2].

Here’s a breakdown of what happens:

The function considers the main diagonal of the given array, which consists of elements [1, 3, 2].
It returns these elements as a 1D array [1, 3, 2].

For arr2 =np.diagflat([[1,2,3,4],[4,3,2,1],[4,3,2,1]]), np.diagflat() automatically flattens the input array and creates a diagonal matrix where the diagonal elements are filled with the flattened values of the input array. This helps avoid the confusion that might arise from misunderstanding the behavior of np.diag() with a 2D array.

trace():

  • to get the sum of diagonal values
np.trace(arr2)
Output:
30

copy():

  • Create a copy of an array
Int_arr = np.array([30, 28, 26, 24, 22, 20, 18, 16, 14, 12])
Copied_arr = Int_arr.copy()
Copied_arr
Output:
array([30, 28, 26, 24, 22, 20, 18, 16, 14, 12])
# Modify initial array 
Int_arr*2
Output:
array([60, 56, 52, 48, 44, 40, 36, 32, 28, 24])
  • Copy array keep the original array, any changes in the original array, have no impact on a copied array. Let’s below code:
Copied_arr  
Output:
array([30, 28, 26, 24, 22, 20, 18, 16, 14, 12])

random:

  • The random is a module present in the NumPy library. This module contains the functions which are used for generating random numbers.

random sample:

  • This is a function that generates random samples from a uniform distribution over the interval [0.0, 1.0), meaning it includes values between 0.0 (inclusive) and 1.0 (exclusive). So, it cannot produce a value exactly equal to 1.0.
  • Create arrays of random numbers with specified shapes. 
ran_sample1=np.random.random_sample() # no argument is provided,returns a single random float. 
print('ran_sample1',ran_sample1)

ran_sample2=np.random.random_sample(3) # Single argument(3) is provided,returns three random float.
print('ran_sample2',ran_sample2)

ran_sample3=np.random.random_sample((3,4)) # two dimensions are provided, returns 2D array
print('ran_sample3',ran_sample3)

ran_sample4=np.random.random_sample((3,4,5)) # three dimensions are provided, returns 2D array
print('ran_sample4',ran_sample4)

Output:
ran_sample1 0.20557151614754843
ran_sample2 [0.17024325 0.03079934 0.82907838]
ran_sample3 [[0.94359773 0.06009933 0.99338837 0.15725629]
 [0.10359726 0.58222964 0.25882986 0.25022372]
 [0.02078739 0.94165748 0.5096122  0.76646347]]
ran_sample4 [[[0.58217402 0.90694487 0.66687329 0.74025215 0.92455318]
  [0.90908458 0.65726499 0.22599511 0.96921949 0.43907181]
  [0.87799682 0.24099743 0.23976914 0.15618271 0.70758492]
  [0.11401432 0.43360478 0.75282128 0.06090399 0.84742065]]

 [[0.86640818 0.22443571 0.26503105 0.60540574 0.95117403]
  [0.39606219 0.51446521 0.26373792 0.17793225 0.75121426]
  [0.05188912 0.71267922 0.30699202 0.71898148 0.84882598]
  [0.40216185 0.47067973 0.91252529 0.83332499 0.62580212]]

 [[0.56959457 0.52896382 0.83786031 0.23620927 0.74765087]
  [0.36571985 0.56880427 0.1606733  0.04492638 0.98706467]
  [0.81809203 0.83888067 0.75852115 0.85824794 0.26591774]
  [0.96657762 0.70385523 0.68556466 0.89239504 0.29631018]]]

rand:

  • Create an array of the given shape & populate it random samples from uniform distribution over [0.0, 1.0), meaning it includes values between 0.0 (inclusive) and 1.0 (exclusive). So, it cannot produce a value exactly equal to 1.0.

Difference between rand & random_sample:

rand() takes a variable number of arguments (d0, d1, …, dn), where d0, d1, …, dn are the dimensions of the output array. It returns an array of random numbers with the specified shape. It is more concise when you want to specify the dimensions directly as separate arguments. For example:

array = np.random.rand(2, 3)

While random_sample() takes one argument size, which specifies the shape of the output array. If size is None (default), a single value is returned. It returns an array of random numbers with the specified shape.is more flexible as it allows you to specify the shape of the output array using a single argument. For example:

array = np.random.random_sample((2, 3))

rand1=np.random.rand() # no argument is provided,returns a single random float. 
print('rand1',rand1)

rand2=np.random.rand(3) # Single argument(3) is provided,returns three random float.
print('rand2',rand2)

rand3=np.random.rand(3,4) # two dimensions are provided, returns 2D array
print('rand3',rand3)

rand4=np.random.rand(3,4,5) # three dimensions are provided, returns 2D array
print('rand4',rand4)
Output:
rand1 0.030614917566486044
rand2 [0.27233297 0.87881822 0.84485869]
rand3 [[0.43034873 0.8712414  0.04586816 0.22121201]
 [0.86781508 0.07721427 0.45531896 0.8525511 ]
 [0.64846383 0.89879316 0.66156502 0.6464079 ]]
rand4 [[[0.93300282 0.98202443 0.49725171 0.3746117  0.83020843]
  [0.65294347 0.05154789 0.17696719 0.73887999 0.06462686]
  [0.96530314 0.47791644 0.57902306 0.34992708 0.17299486]
  [0.86337097 0.85290226 0.1907848  0.92874552 0.84700337]]

 [[0.44824023 0.39832349 0.41413663 0.88716382 0.52862566]
  [0.21460277 0.55080369 0.40002677 0.55831497 0.91621562]
  [0.65190928 0.03881952 0.5156102  0.24450753 0.98814932]
  [0.6463758  0.41677551 0.20973021 0.38487955 0.74294529]]

 [[0.48924653 0.08493566 0.80440262 0.9701826  0.52267842]
  [0.45608909 0.90826733 0.03844716 0.48571911 0.59932421]
  [0.99533405 0.85570383 0.51654059 0.48953599 0.41506915]
  [0.8995896  0.85684558 0.90895738 0.16121246 0.10120177]]]

randn:

  • Return a sample(or samples) from the Standard Normal distribution(mean=0, standard deviation=1).
  • Return an array of random numbers with the specified shape
randn1=np.random.randn() # no argument is provided,returns a single random float. 
print('randn1',randn1)

randn2=np.random.randn(3) # Single argument(3) is provided,returns three random float.
print('randn2',randn2)

randn3=np.random.randn(3,4) # two dimensions are provided, returns 2D array
print('randn3',randn3)

randn4=np.random.randn(3,4,5) # three dimensions are provided, returns 2D array
print('randn4',randn4)
Output:
randn1 -0.3113374807430752
randn2 [-1.16145433  0.13095681 -0.83454288]
randn3 [[ 0.30619294 -0.39409988 -1.51066909  0.33724857]
 [ 0.87895307 -0.25000208 -0.35447013 -0.67441496]
 [ 1.56008764 -0.7116275  -0.31404006  0.60719826]]
randn4 [[[ 0.54526956  0.76810861  0.03492336  1.12875151 -0.61040446]
  [-0.36313815 -1.31015306 -2.17633214 -0.75915684  0.35552676]
  [ 0.80834184  0.64238021 -2.23120019  0.78440104  0.83138921]
  [-0.31256267  1.04325293 -1.58242009 -0.32467802 -1.18505163]]

 [[ 0.31211827  0.23542457 -0.42104826 -0.27740896 -0.60857524]
  [-0.50895796  1.12815836 -0.1037551   1.33076188  1.43417757]
  [-0.22666376 -2.15944174  0.48484984 -1.46181813  1.67520654]
  [ 0.97785673 -0.69230553 -0.47170064  0.82678434  0.67681219]]

 [[ 1.66500635 -2.61137107 -1.2725439  -0.75370018  0.31512839]
  [-0.64558902 -1.49858945 -1.0926292   0.32564715 -0.72116631]
  [ 1.73595266  0.50582961 -0.38039876 -0.58296546 -0.96741266]
  [-0.86895695 -0.21333464 -2.02818536 -0.93284895  0.89083833]]]

randint:

  • Return random integer from lowest (inclusive) integer to highest (exclusive) integer to be drawn from the distribution.
  • If the highest is not provided, the high defaults to None and the value of low is used as the maximum value (exclusive).
randint1 = np.random.randint(1,50) # default it will give one value
print("randint1: ",randint1)

randint2 = np.random.randint(1,50,5) # third argument is how many number required
print("randint2: ",randint2)

# If range is small than required, same number will be repeated to complete total required number
randint3 = np.random.randint(48,50,5) 
print("randint3: ",randint3)
Output:
randint1:  10
randint2:  [10 29 19 11  1]
randint3:  [48 49 48 49 48]

seed():

  • Use to seed the random number generator.
  • Seeding the random number generator allows you to reproduce the same sequence of random numbers every time you run your program.
  • This is particularly useful for debugging and testing purposes when you need deterministic behavior.
np.random.seed(48)  # seed value itself does not have any inherent meaning or importance.

np.random.randint(2,20,5)
Output:
array([ 2, 19,  6, 18,  2])

In this example, I used 48 as a seed argument. If you run this code, every time you will get the same output. But if you change the seed argument, it will give a different output.

If you do not use the seed() function, when you run this code every time you will get a different output. Please try by yourself

max,min,argmax,argmin:

max: This function returns the maximum value in an array.

min: This function returns the minimum value in an array.

argmax: This function returns the indices(index location) of the maximum value(s) in an array.

argmin: This function returns the indices(index location) of the minimum value(s) in an array.

array = np.array([30, 28, 26, 24, 22, 20, 18, 16, 14, 12])

max_value = np.max(array) # Way one
max_value = max(array) #Way two
max_value = array.max() #Way three

print("Maximum value:", max_value)

min_value = np.min(array) # Way one
min_value = min(array) #Way two
min_value = array.min() #Way three

print("Minimum value:", min_value)

argmax_index = np.argmax(array) #Way one
argmax_index = array.argmax() #Way two

print("Index of maximum value:", argmax_index)

argmin_index = np.argmin(array) #Way one
argmin_index = array.argmin() #Way two

print("Index of minimum value:", argmin_index)

Output:
Maximum value: 30
Minimum value: 12
Index of maximum value: 0
Index of minimum value: 9

NumPy Indexing :

  • Indexing: Indexing refers to the process of accessing individual elements or subsets of elements from a NumPy array based on their position or index within the array. It involves specifying one or more indices to access specific elements.
# Importing library & creating array to use for indexing & selection

import numpy as np

arr = np.array([11, 22, 33, 44, 55])
print('arr',arr)

# Get a value at an index from 1D array

value_2 = arr[2]
print("value_2 :",value_2)

# Assigning value to specific indexed position replacing intial value
arr[2]=77
print('arr',arr)

# Get a subset from 1D array
subset1 = arr[[1,3]]
print("subset1 :",subset1)

Output:
arr [11 22 33 44 55]
value_2 : 33
arr [11 22 77 44 55]
subset1 : [22 44]
# Creating 2D array to use for next function

arr1 = np.array([11, 22, 33, 44, 55,66,77,88,99,00])
arr2=arr1.reshape(2,5)
print('arr2 :',arr2)

subset_arr2 = arr2[1,3]
print("subset_arr2 :",subset_arr2)
Output:
arr2 : [[11 22 33 44 55]
        [66 77 88 99  0]]
subset_arr2 : 99
  • In the above example, arr2[1, 3] means we’re accessing the element at the 2nd row (index 1) and the 4th column (index 3). Remember, indices start from 0. So, arr2[1, 3] corresponds to the element in row 2, column 4, which is 99.
# Creating 3D array to use for next function

arr3 = np.array([11, 22, 33, 44, 55,66,77,88,99,10,12,13,14,15,2,3,4,5])
arr_3D=arr3.reshape(2,3,3)
print('arr_3D :',arr_3D)

subset_3D = arr_3D[0,1,2]
print("subset_3D: ",subset_3D)
Output:
arr_3D : [[[11 22 33]
           [44 55 66]
           [77 88 99]]

          [[10 12 13]
           [14 15  2]
           [ 3  4  5]]]
subset_3D:  66

Negative indexing:

  • When you use a negative index to access an element in an array, Python counts backward from the end of the array.
  • For instance, -1 refers to the last element, -2 refers to the second-to-last element, and so on.
subset_3D_neg = arr_3D[-1,-2,-3]
print("subset_3D_neg: ",subset_3D_neg)
Output:
subset_3D_neg:  14

Selection:

  • Refers to the process of choosing elements from a NumPy array based on certain conditions or criteria.
  • This can involve using boolean arrays to filter elements or using fancy indexing to select specific subsets of the array.
arr_selection1 = arr[arr>10]
print('arr_selection1 ',arr_selection1)

arr_selection2 = arr_3D[arr_3D>10]
print('arr_selection2 ',arr_selection2)
Output:
arr_selection1  [11 22 33 44 55]
arr_selection2  [11 22 33 44 55 66 77 88 99 12 13 14 15]

Slicing:

  • Slicing in Python refers to a way of extracting a subset of elements from a sequence like a list, tuple, or string.
  • It allows you to create a new sequence containing a portion of the original sequence.
  • Slicing is done using the square brackets [ ] and the colon : notation.
  • Syntax for slicing: sequence[ start : stop : step ]
    • start: The index where the slicing begins (inclusive).
    • stop: The index where the slicing ends (exclusive).
    • step: Optional. The step size used to specify how many elements to skip. If not provided, it defaults to 1.
import numpy as np

# sample array
arr = np.array([30, 28, 26, 24, 22, 20, 18, 16, 14, 12])


# Slicing with start only which will start from start value till last value of array

slice01 = arr[3:]
print("slice01",slice01)

# Slicing with end only which will give from first value of array till end value excluding end value

slice02 = arr[:9]
print("slice02",slice02)

# Slicing with start & end which will give range of value from start to end( Excluded)

slice03 = arr[2:8]
print("slice03",slice03)

# Negative slicing which count will start from last value ( considered as -1)

slice04 = arr[-8:-3]
print("slice04",slice04)

# Slicing with step which will skip number of step value provided

slice05 = arr[2:9:2]
print("slice05",slice05)

Output:
slice01 [24 22 20 18 16 14 12]
slice02 [30 28 26 24 22 20 18 16 14]
slice03 [26 24 22 20 18 16]
slice04 [26 24 22 20 18]
slice05 [26 22 18 14]

Slicing from 2D Array:

Let’s create 2D array for Slicing 
arr = np.random.randint(5,25,50)
arr = arr.reshape(10,5)
arr
Output:
array([[ 9,  5, 22, 21, 24],
       [22,  7, 19,  5,  8],
       [23, 16,  6, 20,  7],
       [16,  7,  8,  9,  9],
       [21, 17, 20,  5, 15],
       [21, 14,  7, 21,  9],
       [14, 12, 20, 13,  5],
       [ 8,  7, 14, 16, 21],
       [13, 15, 12,  8, 24],
       [ 7, 19, 15, 23,  8]])
arr[3:7,2:4]
Output:
array([[23,  8],
       [22, 17],
       [ 5,  9],
       [18, 11]])
arr[:7,2:]
Output:
array([[10, 14, 20],
       [16,  7, 23],
       [21, 17, 24],
       [19, 15, 18],
       [10,  9, 24],
       [22, 21, 10],
       [10, 13, 10]])
# Slicing from specific row , then slice from column

arr[7,2:]
Output:
array([15, 14, 21])
# Slicing from specific column

arr[:2,3]
Output:
array([19,  7])
# Fancy indexing , slice from specific index number

arr[:,[1,3]]
Output:
array([[ 5, 19],
       [13,  7],
       [14, 14],
       [ 9, 24],
       [18, 23],
       [ 6, 18],
       [15, 23],
       [ 6, 24],
       [23,  6],
       [22, 11]])
# Slice in an order

arr[:,[3,1]]
Output:
array([[19,  5],
       [ 7, 13],
       [14, 14],
       [24,  9],
       [23, 18],
       [18,  6],
       [23, 15],
       [24,  6],
       [ 6, 23],
       [11, 22]])
# Slice only specific row

arr[[1,3]]
Output:
array([[ 7, 13,  8,  7, 10],
       [23,  9, 13, 24, 17]])
# Assigning value to specific slice

arr[3:7,2:4]=100
arr
Output:
array([[ 17,  17,   7,   8,  18],
       [  6,  13,  20,  17,  14],
       [ 23,  18,   5,   9,  22],
       [  6,  18, 100, 100,  20],
       [ 15,  17, 100, 100,  23],
       [ 20,  10, 100, 100,  20],
       [ 23,   6, 100, 100,  22],
       [ 10,  24,  23,   6,  15],
       [  9,  16,  22,  10,   6],
       [  6,  22,   7,  15,  12]])

Filtering with Condition:

  • It gives the index position in output for the provided value from the array
arr = np.array([30, 28, 26, 24, 22, 20, 18, 35, 16, 40, 14, 12])
arr1 = np.array([31, 29, 26, 25, 22, 21, 18, 37, 18, 43, 11, 12])

greater=np.where(arr>20)
lesser=np.where(arr<20)
equal=np.where(arr==20)
equal_array=np.where(arr==arr1)

print(greater)
print(lesser)
print(equal)
print(equal_array)
Output:
(array([0, 1, 2, 3, 4, 7, 9]),)
(array([ 6,  8, 10, 11]),)
(array([5]),)
(array([ 2,  4,  6, 11]),)

NumPy Operations:

Arithmatic:

# Creating array for next function

arr1 = np.arange(10,30)
print('arr1 :',arr1)

arr2=np.arange(40,60)
print('arr2 :',arr2)
Output:
arr1 : [10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29]
arr2 : [40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59]
# Addition array , shape of both array should be same

arr1+arr2
Output:
array([50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82,84, 86, 88])
#Subtraction array , shape of both array should be same

print(arr1-arr2)
print(arr2-arr1)
Output:
[-30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30 -30
-30 -30]
[30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30]
# Multiplication of array

print(arr1*arr2)

print(arr1*4)
Output:
[ 400  451  504  559  616  675  736  799  864  931 1000 1071 1144 1219
 1296 1375 1456 1539 1624 1711]
[ 40  44  48  52  56  60  64  68  72  76  80  84  88  92  96 100 104 108
 112 116]
# Multiplication of two matrix

p = [[1,0],
        [0,1]]
q = [[1,2],
        [3,4]]


np.dot(p,q)
Output:
array([[1, 2],
       [3, 4]])

Explanation:

For element (1,1) of the resulting matrix:

  • Row 1 of matrix : [1, 0]
  • Column 1 of matrix : [1, 3]
  • Dot product: 1∗1+0∗3

For element (1,2) of the resulting matrix:

  • Row 1 of matrix : [1, 0]
  • Column 2 of matrix : [2, 4]
  • Dot product: 1∗2+0∗4=2

For element (2,1) of the resulting matrix:

  • Row 2 of matrix : [0, 1]
  • Column 1 of matrix : [1, 3]
  • Dot product: 0∗1+1∗3=3

For element (2,2) of the resulting matrix:

  • Row 2 of matrix : [0, 1]
  • Column 2 of matrix : [2, 4]
  • Dot product: 0∗2+1∗4=4

 

# Division of array

array1 = np.array([10, 20, 30])
array2 = np.array([2, 4, 6])

result = array1 / array2

print(array1 / array2)
print('----------------')
print(array1/2)
print('----------------')
print(12/array2)
Output:
[5. 5. 5.]
----------------
[ 5. 10. 15.]
----------------
[6. 3. 2.]
# Power of operator

arrp = np.array([2, 4, 6])

arrp**2 # or below

pow(arrp,2)   #pow(base, exp)
Output:
array([ 4, 16, 36])
# Square roots

arrs = np.array([4, 9, 16])
np.sqrt(arrs)
Output:
array([2., 3., 4.])
# Calculating exponential (e^)

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

np.exp(arre)
Output:
array([ 2.71828183,  7.3890561 , 20.08553692])

Register

Login here

Forgot your password?

ads

ads

I am an enthusiastic advocate for the transformative power of data in the fashion realm. Armed with a strong background in data science, I am committed to revolutionizing the industry by unlocking valuable insights, optimizing processes, and fostering a data-centric culture that propels fashion businesses into a successful and forward-thinking future. - Masud Rana, Certified Data Scientist, IABAC

© Data4Fashion 2023-2024

Developed by: Behostweb.com

Please accept cookies
Accept All Cookies