7️⃣

# 3.7 NumPy 2: Linear Algebra

Linear algebra is the subject involving vector and matrix operations. NumPy makes linear algebra a lot easier, so let's find out how to use it to do what we discussed in the previous math lesson.

To perform addition/subtraction, we can use the + or - operator between two matrices. For example:
u = np.array([0, 1, 2])
v = np.array([1, 2, 3])

# w = [1, 3, 5]
w = u + v
# x = [-1, -1, -1]
x = u - v
The above code will create two NumPy arrays, and their sum is stored in w, while their difference is stored in x. If you had to do this without NumPy, things would be a lot harder. We can do the same for any -dimensional NumPy array as long as the arrays have the same dimensions.

## Scalar Multiplication

To perform scalar multiplication, we just use the * operator between a scalar and a matrix. For example:
# z = [3, 6, 9]
z = 3 * np.array([1, 2, 3])
The above code stores the NumPy array in z.

## Dot Product

The dot product is done by a in-built function: np.dot(x, y).
u = np.array([1, 2])
v = np.array([2, 3])

# z = 8
z = np.dot(u, v)

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

# z = [2, 3, 4, 5, 6, 7, 8, 9, 10]
This is a bit of a unique operation that NumPy allows. Broadcasting allows us to add a number to every element of the array.

## Matrix Multiplication

# returns a * b
np.dot(a, b)
The dot function from the NumPy library would just multiply inputs if you enter constants. If you input 1-dimensional NumPy arrays, it returns the dot product as discussed earlier. If you enter 2D NumPy arrays, the np.dot will multiply the two matrices together.
For example,
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

np.dot(a, b)
signifies the following multiplication:

## Statistical Functions

NumPy arrays have some useful statistical functions as well. We'll discuss some of them here.

### Mean

We can calculate the mean, or average, of all the elements in a numpy array using the .mean() method.
numpyArray.mean()

### Minimum and Maximum

numpyArray.min()
outputs the minimum element in the array, and
numpyArray.max()
produces the maximum element in the array.

### Sampling

This is not exactly what you think of when you hear the word "sampling". The np.linspace() method returns a NumPy array that an array of "samples." Let's see what that means:
np.linspace(a, b, n)
Here, a represents the initial value, b represents the end value, and n represents the number of samples. As such, np.linspace(a, b, n) will return n numbers linearly spaced from a to b. Let's see an of how that works:
# [1, 2.3333, 3.6667, 5]
np.linspace(1, 5, 4)
However, linspace has a provision for an open interval as well. This means that the samples taken don't include the endpoint:
np.linspace(1,5,4,True): [1, 2.3333, 3.6667, 5]
np.linspace(1,5,4,False): [1, 2, 3, 4]
We'll often use linspace for plotting.

### Transpose

Finally, to take the transpose of an array, you can use the following code:
numpyArray.T
Provides the transpose of the NumpyArray

### Random.rand

We will be using this in splitting up our data. The
np.random.rand(n)
function takes the dimensions of an array, and produces an array of the same size filled with random values between 0 and 1. We will use this as a way to split up data into slightly randomized categories.

And that's it! NumPy functionalities are not very easy to remember either, but you can refer back to this later.

## Next Section

Add a page link block here (if there is no next section, delete this column)

⚖️