pag. 01

Array Vectors

 
""" NUMPY - ARRAY (VECTORS)
---------------------------
A vector is an one-dimensional array.
"""

import numpy as np
from icecream import ic

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

ic(row)
ic(col)

"""
ic| row: array([1, 2, 3])
ic| col: array([[1],
                [2],
                [3]])
"""

Array Matrices

 
""" NUMPY - ARRAY (MATRICES)
----------------------------
Numpy main data structure is the multidimensional array.
"""

import numpy as np
from icecream import ic

# Matrix (three rows, four columns)
M = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12],
])

ic(M)
ic(M.shape)
ic(M.size)
ic(M.ndim)  # array dimension number


"""
ic| row: array([1, 2, 3])
ic| col: array([[1],
                [2],
                [3]])
ic| M.shape: (3, 4)
ic| M.size: 12
ic| M.ndim: 2
"""

NumPy Vectorize

 
""" NUMPAY - VECTORIZE
----------------------
In NumPy, vectorize allows you to apply a normal Python function
to each element of a NumPy array.

It is mainly for convenience and readability, not performance.

Example:
  Create a vectorized function that adds 100 to each element it receives.
  The function is applied to each element of the array A individually
"""

import numpy as np

A = np.array([  # 2D NumPy array (matrix) with integer values
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
])

B = np.vectorize(lambda x: x + 1)(A)

print(B)

"""
[[ 2  3  4]
 [ 5  6  7]
 [ 8  9 10]]
"""

C = A + 100  # broadcasting (different dimensions allowed)

print(C)

"""
[[101 102 103]
 [104 105 106]
 [107 108 109]]
"""

Sparse Matrices

 
""" NUMPY - SPARCE MATRICES
----------------------------
A sparse matrix stores only non-zero elements, for computation savings.
Compress sparce row (CSR) matrices contain indexes of non-zero values.

Sample: 
Netfilx movie/users count:
    - Every column represents a movie
    - Every row represents an user.

On values we have how many times each user watched that movie.
We can see that we have multiple zero values, which is normal.
"""

import numpy as np
from scipy import sparse

M = np.array([
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], # User vector
    [0, 1, 0, 0, 0, 0, 0, 0, 0, 0], 
    [3, 0, 0, 0, 0, 0, 0, 0, 0, 0], 
])

sparse_matrix = sparse.csr_matrix(M)

print(sparse_matrix)

#  (1, 1)        1
#  (2, 0)        3

print("User[2] watched the movie[0]: ", sparse_matrix[2, 0])

# User[2] watched the movie[0]:  3

Random Matrices

 
""" NUMPY - MATRICES (RANDOM GENERATED)
---------------------------------------
"""

import numpy as np

np.random.seed(0)

A = np.random.random(3)  # floats
B = np.random.randint(1, 11, 3)  # integers

print(A)  # [0.5488135  0.71518937 0.60276338]
print(B)  # [ 4  8 10]

Matrix Operations

 
""" NUMPY - MATRIX OPERATIONS
-----------------------------
"""

import numpy as np


""" MIN, MAX, AVG """

M = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
])

max = np.max(M)
min = np.min(M)
avg = np.mean(M)

print(f"Max: {max}")  # 9
print(f"Min: {min}")  # 1
print(f"Avg: {avg}")  # 5.0

max = np.max(M, axis=1)  # max in each row
min = np.min(M, axis=1)
avg = np.mean(M, axis=0)

print(f"Max in each row: {max}")  # [3 6 9]
print(f"Min in each row: {min}")  # [1 4 7]
print(f"Avg in each row: {avg}")  # [4. 5. 6.]


""" RESHAPE """

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

A = M.reshape(2, 6)
B = M.reshape(1, -1)
C = M.flatten()

print(f"Matrix:\n {M}")
print(f"Reshape(2,6):\n {A}")
print(f"Reshape(1,-1):\n {B}")
print(f"Flattern:\n {C}")

"""
    Reshape(2,6):
    [[ 1  2  3  4  5  6]
     [ 7  8  9 10 11 12]]
    Reshape(1,-1):
    [[ 1  2  3  4  5  6  7  8  9 10 11 12]]
    Flattern:
    [ 1  2  3  4  5  6  7  8  9 10 11 12]
"""


""" TRANSPOSE """

M = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
])

print(f"Transpose: {M.T}")

"""
    [[1 4 7]
     [2 5 8]
     [3 6 9]]
"""


""" INVERSE """

M = np.array([
  [4, 3],
  [3, 2],
])

A = np.linalg.inv(M)

I = np.array([  # Identy Matrix
    [1, 0],
    [0, 1]
])

assert (M @ A == I).all()
assert (A @ M == I).all()

print(f"Inverse: {A}")

"""
    [[-2.  3.]
     [ 3. -4.]]
"""



""" ADDITION & SUBSTRACTION """

A = np.array([
    [1, 1],
    [2, 2],
])

B = np.array([
    [1, 1],
    [3, 3],
])

C = A + B

print(f"Addition:\n {A} +\n\n {B} =\n\n {C}")

"""
    [[1 1]
     [2 2]] +

    [[1 1]
     [3 3]] =

    [[2 2]
     [5 5]]
"""


""" MULTIPLICATION """

A = np.array([
    [1, 1],
    [2, 2],
])

B = np.array([
    [1, 1],
    [3, 3],
])

C = A @ B  # OR

E = A * B  # Element-wise multiplication

print(f"Multiplication:\n {A} @\n\n {B} =\n\n {C}")
print(f"Element-wise Multiplication:\n {A} *\n\n {B} =\n\n {E}")

"""
    Multiplication:

    [[1 1]
     [2 2]] @

    [[1 1]
     [3 3]] =

    [[4 4]
     [8 8]
     ]
    Element-wise Multiplication:
    
    [[1 1]
     [2 2]] *

    [[1 1]
     [3 3]] =

    [[1 1]
     [6 6]]
"""

Linspace

 
""" NUMPY - LINSPACE
******--
numpy.linspacee(start, stop, n)
Creates a list of evenly spaced number between start and stop
(including both ends), using exaclty n points.

Example: Simulate temperature increase during the morning
We know:
    - At 08:00 the temperature is 10C
    - At 12:00 the temperature is 20C
    - We want 5 equally spaced points between these times
"""

import numpy as np

temperatures = np.linspace(10, 20, 5)

print(temperatures)  # [10.  12.5 15.  17.5 20. ]




References: