Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mrdbourke
GitHub Repository: mrdbourke/zero-to-mastery-ml
Path: blob/master/section-2-data-science-and-ml-tools/numpy-exercises-solutions.ipynb
874 views
Kernel: Python 3

NumPy Practice (solutions)

This notebook offers a set of solutions to different tasks with NumPy.

It should be noted there may be more than one different way to answer a question or complete an exercise.

Exercises are based off (and directly taken from) the quick introduction to NumPy notebook.

Different tasks will be detailed by comments or text.

For further reference and resources, it's advised to check out the NumPy documentation.

# Import NumPy as its abbreviation 'np' import numpy as np
# Create a 1-dimensional NumPy array using np.array() a1 = np.array([1, 2, 3]) # Create a 2-dimensional NumPy array using np.array() a2 = np.array([[1, 2, 3], [4, 5, 6]]) # Create a 3-dimensional Numpy array using np.array() a3 = np.array([[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]]])

Now we've you've created 3 different arrays, let's find details about them.

Find the shape, number of dimensions, data type, size and type of each array.

# Attributes of 1-dimensional array a1.shape, a1.ndim, a1.dtype, a1.size, type(a1)
((3,), 1, dtype('int64'), 3, numpy.ndarray)
# Attributes of 2-dimensional array a2.shape, a2.ndim, a2.dtype, a2.size, type(a2)
((2, 3), 2, dtype('int64'), 6, numpy.ndarray)
# Attributes of 3-dimensional array a3.shape, a3.ndim, a3.dtype, a3.size, type(a3)
((2, 3, 3), 3, dtype('int64'), 18, numpy.ndarray)
# Import pandas and create a DataFrame out of one # of the arrays you've created import pandas as pd df = pd.DataFrame(a2) df
# Create an array of shape (10, 2) with only ones ones = np.ones((10, 2)) ones
array([[1., 1.], [1., 1.], [1., 1.], [1., 1.], [1., 1.], [1., 1.], [1., 1.], [1., 1.], [1., 1.], [1., 1.]])
# Create an array of shape (7, 2, 3) of only zeros zeros = np.zeros((7, 2, 3)) zeros
array([[[0., 0., 0.], [0., 0., 0.]], [[0., 0., 0.], [0., 0., 0.]], [[0., 0., 0.], [0., 0., 0.]], [[0., 0., 0.], [0., 0., 0.]], [[0., 0., 0.], [0., 0., 0.]], [[0., 0., 0.], [0., 0., 0.]], [[0., 0., 0.], [0., 0., 0.]]])
# Create an array within a range of 0 and 100 with step 3 range_array = np.arange(0, 100, 3) range_array
array([ 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99])
# Create a random array with numbers between 0 and 10 of size (7, 2) random_array = np.random.randint(10, size=(7, 2)) random_array
array([[8, 7], [9, 9], [1, 9], [1, 5], [8, 7], [6, 6], [0, 4]])
# Create a random array of floats between 0 & 1 of shape (3, 5) np.random.random((3, 5))
array([[0.75480126, 0.63027896, 0.00432216, 0.82660043, 0.76376716], [0.85392685, 0.22136242, 0.51595776, 0.57397845, 0.87653345], [0.21496518, 0.99913323, 0.29537964, 0.31380183, 0.59812565]])
# Set the random seed to 42 np.random.seed(42) # Create a random array of numbers between 0 & 10 of size (4, 6) np.random.randint(10, size=(4, 6))
array([[6, 3, 7, 4, 6, 9], [2, 6, 7, 4, 3, 7], [7, 2, 5, 4, 1, 7], [5, 1, 4, 0, 9, 5]])

Run the cell above again, what happens?

Are the numbers in the array different or the same? Why do think this is?

# Create an array of random numbers between 1 & 10 of size (3, 7) # and save it to a variable array = np.random.randint(1, 10, size=(3, 7)) # Find the unique numbers in the array you just created np.unique(array)
array([1, 2, 3, 4, 5, 7, 9])
# Find the 0'th index of the latest array you created array[0]
array([9, 1, 3, 7, 4, 9, 3])
# Get the first 2 rows of latest array you created array[:2]
array([[9, 1, 3, 7, 4, 9, 3], [5, 3, 7, 5, 9, 7, 2]])
# Get the first 2 values of the first 2 rows of the latest array array[:2, :2]
array([[9, 1], [5, 3]])
# Create a random array of numbers between 0 & 10 and an array of ones # both of size (3, 5), save them both to variables a4 = np.random.randint(10, size=(3, 5)) ones = np.ones((3, 5))
# Add the two arrays together a4 + ones
array([[ 7., 8., 3., 1., 4.], [ 2., 8., 4., 2., 6.], [ 6., 10., 4., 6., 2.]])
# Create another array of ones of shape (5, 3) ones = np.ones((5, 3))
# Try to add the array of ones and the other most recent array together a4 + ones
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-20-c7305efdb212> in <module> 1 # Try add the array of ones and the other most recent array together ----> 2 a4 + ones ValueError: operands could not be broadcast together with shapes (3,5) (5,3)

When you try the last cell, it produces an error. Why do think this is?

How would you fix it?

# Create another array of ones of shape (3, 5) ones = np.ones((3, 5))
# Subtract the new array of ones from the other most recent array a4 - ones
array([[ 5., 6., 1., -1., 2.], [ 0., 6., 2., 0., 4.], [ 4., 8., 2., 4., 0.]])
# Multiply the ones array with the latest array a4 * ones
array([[6., 7., 2., 0., 3.], [1., 7., 3., 1., 5.], [5., 9., 3., 5., 1.]])
# Take the latest array to the power of 2 using '**' a4 ** 2
array([[36, 49, 4, 0, 9], [ 1, 49, 9, 1, 25], [25, 81, 9, 25, 1]])
# Do the same thing with np.square() np.square(a4)
array([[36, 49, 4, 0, 9], [ 1, 49, 9, 1, 25], [25, 81, 9, 25, 1]])
# Find the mean of the latest array using np.mean() np.mean(a4)
3.8666666666666667
# Find the maximum of the latest array using np.max() np.max(a4)
9
# Find the minimum of the latest array using np.min() np.min(a4)
0
# Find the standard deviation of the latest array np.std(a4)
2.578543947441829
# Find the variance of the latest array np.var(a4)
6.648888888888889
# Reshape the latest array to (3, 5, 1) a4.reshape(3, 5, 1)
array([[[6], [7], [2], [0], [3]], [[1], [7], [3], [1], [5]], [[5], [9], [3], [5], [1]]])
# Transpose the latest array a4.T
array([[6, 1, 5], [7, 7, 9], [2, 3, 3], [0, 1, 5], [3, 5, 1]])

What does the transpose do?

# Create two arrays of random integers between 0 to 10 # one of size (3, 3) the other of size (3, 2) mat1 = np.random.randint(10, size=(3, 3)) mat2 = np.random.randint(10, size=(3, 2))
# Perform a dot product on the two newest arrays you created np.dot(mat1, mat2)
array([[ 88, 117], [100, 123], [ 89, 127]])
# Create two arrays of random integers between 0 to 10 # both of size (4, 3) mat3 = np.random.randint(10, size=(4, 3)) mat4 = np.random.randint(10, size=(4, 3))
# Perform a dot product on the two newest arrays you created np.dot(mat3, mat4)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-36-ee8f632a580a> in <module> 1 # Perform a dot product on the two newest arrays you created ----> 2 np.dot(mat3, mat4) <__array_function__ internals> in dot(*args, **kwargs) ValueError: shapes (4,3) and (4,3) not aligned: 3 (dim 1) != 4 (dim 0)

It doesn't work. How would you fix it?

# Take the latest two arrays, perform a transpose on one of them and then perform # a dot product on them both np.dot(mat3.T, mat4)
array([[128, 90, 128], [184, 91, 151], [ 42, 14, 40]])

Notice how performing a transpose allows the dot product to happen.

Why is this?

Checking out the documentation on np.dot() may help, as well as reading Math is Fun's guide on the dot product.

Let's now compare arrays.

# Create two arrays of random integers between 0 & 10 of the same shape # and save them to variables mat5 = np.random.randint(10, size=(4, 2)) mat6 = np.random.randint(10, size=(4, 2))
# Compare the two arrays with '>' mat5 > mat6
array([[ True, True], [ True, True], [ True, True], [False, False]])

What happens when you compare the arrays with >?

# Compare the two arrays with '>=' mat5 >= mat6
array([[ True, True], [ True, True], [ True, True], [False, False]])
# Find which elements of the first array are greater than 7 mat5 > 7
array([[False, False], [False, False], [False, False], [False, False]])
# Which parts of each array are equal? (try using '==') mat5 == mat6
array([[False, False], [False, False], [False, False], [False, False]])
# Sort one of the arrays you just created in ascending order np.sort(mat5)
array([[6, 6], [4, 7], [2, 7], [2, 5]])
# Sort the indexes of one of the arrays you just created np.argsort(mat6)
array([[0, 1], [1, 0], [0, 1], [1, 0]])
# Find the index with the maximum value in one of the arrays you've created np.argmax(mat5)
2
# Find the index with the minimum value in one of the arrays you've created np.argmin(mat6)
0
# Find the indexes with the maximum values down the 1st axis (axis=1) # of one of the arrays you created np.argmax(mat5, axis=1)
array([0, 0, 1, 0])
# Find the indexes with the minimum values across the 0th axis (axis=0) # of one of the arrays you created np.argmin(mat6, axis=0)
array([0, 0])
# Create an array of normally distributed random numbers np.random.randn(3, 5)
array([[-0.03582604, 1.56464366, -2.6197451 , 0.8219025 , 0.08704707], [-0.29900735, 0.09176078, -1.98756891, -0.21967189, 0.35711257], [ 1.47789404, -0.51827022, -0.8084936 , -0.50175704, 0.91540212]])
# Create an array with 10 evenly spaced numbers between 1 and 100 np.linspace(1, 100, 10)
array([ 1., 12., 23., 34., 45., 56., 67., 78., 89., 100.])

Extensions

For more exercises, check out the NumPy quickstart tutorial. A good practice would be to read through it and for the parts you find interesting, add them into the end of this notebook.

Pay particular attention to the section on broadcasting. And most importantly, get hands-on with the code as much as possible. If in dobut, run the code, see what it does.

The next place you could go is the Stack Overflow page for the top questions and answers for NumPy. Often, you'll find some of the most common and useful NumPy functions here. Don't forget to play around with the filters! You'll likely find something helpful here.

Finally, as always, remember, the best way to learn something new is to try it. And try it relentlessly. If you get interested in some kind of NumPy function, asking yourself, "I wonder if NumPy could do that?", go and find out.