0% found this document useful (0 votes)
2 views19 pages

Complete NumPy Notes With Examples and Exercises

NumPy is a crucial Linear Algebra Library for Python, widely used in Data Science due to its speed and foundational role in the PyData Ecosystem. The document provides installation instructions, basic usage, and methods for creating and manipulating NumPy arrays, including functions for generating sequences, random numbers, and array attributes. It also covers indexing, selection, and broadcasting of arrays, emphasizing the differences between NumPy arrays and standard Python lists.

Uploaded by

SHUCHI SHUKLA
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)
2 views19 pages

Complete NumPy Notes With Examples and Exercises

NumPy is a crucial Linear Algebra Library for Python, widely used in Data Science due to its speed and foundational role in the PyData Ecosystem. The document provides installation instructions, basic usage, and methods for creating and manipulating NumPy arrays, including functions for generating sequences, random numbers, and array attributes. It also covers indexing, selection, and broadcasting of arrays, emphasizing the differences between NumPy arrays and standard Python lists.

Uploaded by

SHUCHI SHUKLA
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
You are on page 1/ 19

No description has been provided for this image

NumPy
NumPy (or Numpy) is a Linear Algebra Library for Python, the reason it is so
important for Data Science with Python is that almost all of the libraries in the
PyData Ecosystem rely on NumPy as one of their main building blocks.

Numpy is also incredibly fast, as it has bindings to C libraries. For more info on why
you would want to use Arrays instead of lists, check out this great StackOverflow
post.

We will only learn the basics of NumPy, to get started we need to install it!

Installation Instructions
It is highly recommended you install Python using the Anaconda
distribution to make sure all underlying dependencies (such as Linear
Algebra libraries) all sync up with the use of a conda install. If you have
Anaconda, install NumPy by going to your terminal or command prompt
and typing:

conda install numpy

If you do not have Anaconda and can not install it, please refer to
Numpy's official documentation on various installation instructions.

Using NumPy
Once you've installed NumPy you can import it as a library:

In [1]: import numpy as np

Numpy has many built-in functions and capabilities. We won't cover them all but
instead we will focus on some of the most important aspects of Numpy:
vectors,arrays,matrices, and number generation. Let's start by discussing arrays.
Numpy Arrays
NumPy arrays are the main way we will use Numpy throughout the course. Numpy
arrays essentially come in two flavors: vectors and matrices. Vectors are strictly
1-d arrays and matrices are 2-d (but you should note a matrix can still have only
one row or one column).

Let's begin our introduction by exploring how to create NumPy arrays.

Creating NumPy Arrays


From a Python List
We can create an array by directly converting a list or list of lists:

In [19]: my_list = [1,2,3]


my_list

Out[19]: [1, 2, 3]

In [16]: np.array(my_list)

Out[16]: array([1, 2, 3])

In [20]: my_matrix = [[1,2,3],[4,5,6],[7,8,9]]


my_matrix

Out[20]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [21]: np.array(my_matrix)

Out[21]: array([[1, 2, 3],


[4, 5, 6],
[7, 8, 9]])

Built-in Methods
There are lots of built-in ways to generate Arrays

arange
Return evenly spaced values within a given interval.
In [22]: np.arange(0,10)

Out[22]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [23]: np.arange(0,11,2)

Out[23]: array([ 0, 2, 4, 6, 8, 10])

zeros and ones


Generate arrays of zeros or ones

In [24]: np.zeros(3)

Out[24]: array([ 0., 0., 0.])

In [26]: np.zeros((5,5))

Out[26]: 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.]])

In [27]: np.ones(3)

Out[27]: array([ 1., 1., 1.])

In [28]: np.ones((3,3))

Out[28]: array([[ 1., 1., 1.],


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

linspace
Return evenly spaced numbers over a specified interval.

In [29]: np.linspace(0,10,3)

Out[29]: array([ 0., 5., 10.])

In [31]: np.linspace(0,10,50)
Out[31]: array([ 0. , 0.20408163, 0.40816327, 0.6122449 ,
0.81632653, 1.02040816, 1.2244898 , 1.42857143,
1.63265306, 1.83673469, 2.04081633, 2.24489796,
2.44897959, 2.65306122, 2.85714286, 3.06122449,
3.26530612, 3.46938776, 3.67346939, 3.87755102,
4.08163265, 4.28571429, 4.48979592, 4.69387755,
4.89795918, 5.10204082, 5.30612245, 5.51020408,
5.71428571, 5.91836735, 6.12244898, 6.32653061,
6.53061224, 6.73469388, 6.93877551, 7.14285714,
7.34693878, 7.55102041, 7.75510204, 7.95918367,
8.16326531, 8.36734694, 8.57142857, 8.7755102 ,
8.97959184, 9.18367347, 9.3877551 , 9.59183673,
9.79591837, 10. ])

eye
Creates an identity matrix

In [37]: np.eye(4)

Out[37]: array([[ 1., 0., 0., 0.],


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

Random
Numpy also has lots of ways to create random number arrays:

rand
Create an array of the given shape and populate it with random samples from a
uniform distribution over [0, 1) .

In [47]: np.random.rand(2)

Out[47]: array([ 0.11570539, 0.35279769])

In [46]: np.random.rand(5,5)

Out[46]: array([[ 0.66660768, 0.87589888, 0.12421056, 0.65074126, 0.60260888],


[ 0.70027668, 0.85572434, 0.8464595 , 0.2735416 , 0.10955384],
[ 0.0670566 , 0.83267738, 0.9082729 , 0.58249129, 0.12305748],
[ 0.27948423, 0.66422017, 0.95639833, 0.34238788, 0.9578872 ],
[ 0.72155386, 0.3035422 , 0.85249683, 0.30414307, 0.79718816]])
randn
Return a sample (or samples) from the "standard normal" distribution. Unlike rand
which is uniform:

In [48]: np.random.randn(2)

Out[48]: array([-0.27954018, 0.90078368])

In [45]: np.random.randn(5,5)

Out[45]: array([[ 0.70154515, 0.22441999, 1.33563186, 0.82872577, -0.28247509],


[ 0.64489788, 0.61815094, -0.81693168, -0.30102424, -0.29030574],
[ 0.8695976 , 0.413755 , 2.20047208, 0.17955692, -0.82159344],
[ 0.59264235, 1.29869894, -1.18870241, 0.11590888, -0.09181687],
[-0.96924265, -1.62888685, -2.05787102, -0.29705576, 0.68915542]])

randint
Return random integers from low (inclusive) to high (exclusive).

In [50]: np.random.randint(1,100)

Out[50]: 44

In [51]: np.random.randint(1,100,10)

Out[51]: array([13, 64, 27, 63, 46, 68, 92, 10, 58, 24])

Array Attributes and Methods


Let's discuss some useful attributes and methods or an array:

In [55]: arr = np.arange(25)


ranarr = np.random.randint(0,50,10)

In [56]: arr

Out[56]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,


17, 18, 19, 20, 21, 22, 23, 24])

In [57]: ranarr

Out[57]: array([10, 12, 41, 17, 49, 2, 46, 3, 19, 39])


Reshape
Returns an array containing the same data with a new shape.

In [54]: arr.reshape(5,5)

Out[54]: array([[ 0, 1, 2, 3, 4],


[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19],
[20, 21, 22, 23, 24]])

max,min,argmax,argmin
These are useful methods for finding max or min values. Or to find their index
locations using argmin or argmax

In [64]: ranarr

Out[64]: array([10, 12, 41, 17, 49, 2, 46, 3, 19, 39])

In [61]: ranarr.max()

Out[61]: 49

In [62]: ranarr.argmax()

Out[62]: 4

In [63]: ranarr.min()

Out[63]: 2

In [60]: ranarr.argmin()

Out[60]: 5

Shape
Shape is an attribute that arrays have (not a method):

In [65]: # Vector
arr.shape

Out[65]: (25,)

In [66]: # Notice the two sets of brackets


arr.reshape(1,25)

Out[66]: array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,


17, 18, 19, 20, 21, 22, 23, 24]])

In [69]: arr.reshape(1,25).shape

Out[69]: (1, 25)

In [70]: arr.reshape(25,1)

Out[70]: array([[ 0],


[ 1],
[ 2],
[ 3],
[ 4],
[ 5],
[ 6],
[ 7],
[ 8],
[ 9],
[10],
[11],
[12],
[13],
[14],
[15],
[16],
[17],
[18],
[19],
[20],
[21],
[22],
[23],
[24]])

In [76]: arr.reshape(25,1).shape

Out[76]: (25, 1)

dtype
You can also grab the data type of the object in the array:

In [75]: arr.dtype

Out[75]: dtype('int64')

Great Job!
No description has been provided for this image

NumPy Indexing and Selection


In this lecture we will discuss how to select elements or groups of elements from an
array.

In [2]: import numpy as np

In [3]: #Creating sample array


arr = np.arange(0,11)

In [4]: #Show
arr

Out[4]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

Bracket Indexing and Selection


The simplest way to pick one or some elements of an array looks very similar to
python lists:

In [5]: #Get a value at an index


arr[8]

Out[5]: 8

In [6]: #Get values in a range


arr[1:5]

Out[6]: array([1, 2, 3, 4])

In [7]: #Get values in a range


arr[0:5]

Out[7]: array([0, 1, 2, 3, 4])

Broadcasting
Numpy arrays differ from a normal Python list because of their ability to broadcast:

In [8]: #Setting a value with index range (Broadcasting)


arr[0:5]=100

#Show
arr

Out[8]: array([100, 100, 100, 100, 100, 5, 6, 7, 8, 9, 10])

In [9]: # Reset array, we'll see why I had to reset in a moment


arr = np.arange(0,11)

#Show
arr

Out[9]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

In [10]: #Important notes on Slices


slice_of_arr = arr[0:6]

#Show slice
slice_of_arr

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

In [11]: #Change Slice


slice_of_arr[:]=99

#Show Slice again


slice_of_arr

Out[11]: array([99, 99, 99, 99, 99, 99])

Now note the changes also occur in our original array!

In [12]: arr

Out[12]: array([99, 99, 99, 99, 99, 99, 6, 7, 8, 9, 10])

Data is not copied, it's a view of the original array! This avoids memory problems!

In [13]: #To get a copy, need to be explicit


arr_copy = arr.copy()

arr_copy

Out[13]: array([99, 99, 99, 99, 99, 99, 6, 7, 8, 9, 10])

Indexing a 2D array (matrices)


The general format is arr_2d[row][col] or arr_2d[row,col]. I recommend usually
using the comma notation for clarity.

In [14]: arr_2d = np.array(([5,10,15],[20,25,30],[35,40,45]))

#Show
arr_2d

Out[14]: array([[ 5, 10, 15],


[20, 25, 30],
[35, 40, 45]])

In [15]: #Indexing row


arr_2d[1]

Out[15]: array([20, 25, 30])

In [16]: # Format is arr_2d[row][col] or arr_2d[row,col]

# Getting individual element value


arr_2d[1][0]

Out[16]: 20

In [17]: # Getting individual element value


arr_2d[1,0]

Out[17]: 20

In [18]: # 2D array slicing

#Shape (2,2) from top right corner


arr_2d[:2,1:]

Out[18]: array([[10, 15],


[25, 30]])

In [19]: #Shape bottom row


arr_2d[2]

Out[19]: array([35, 40, 45])

In [20]: #Shape bottom row


arr_2d[2,:]

Out[20]: array([35, 40, 45])

Fancy Indexing
Fancy indexing allows you to select entire rows or columns out of order,to show
this, let's quickly build out a numpy array:
In [21]: #Set up matrix
arr2d = np.zeros((10,10))

In [22]: #Length of array


arr_length = arr2d.shape[1]

In [23]: #Set up array

for i in range(arr_length):
arr2d[i] = i

arr2d

Out[23]: array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[ 3., 3., 3., 3., 3., 3., 3., 3., 3., 3.],
[ 4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
[ 5., 5., 5., 5., 5., 5., 5., 5., 5., 5.],
[ 6., 6., 6., 6., 6., 6., 6., 6., 6., 6.],
[ 7., 7., 7., 7., 7., 7., 7., 7., 7., 7.],
[ 8., 8., 8., 8., 8., 8., 8., 8., 8., 8.],
[ 9., 9., 9., 9., 9., 9., 9., 9., 9., 9.]])

Fancy indexing allows the following

In [24]: arr2d[[2,4,6,8]]

Out[24]: array([[ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[ 4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
[ 6., 6., 6., 6., 6., 6., 6., 6., 6., 6.],
[ 8., 8., 8., 8., 8., 8., 8., 8., 8., 8.]])

In [25]: #Allows in any order


arr2d[[6,4,2,7]]

Out[25]: array([[ 6., 6., 6., 6., 6., 6., 6., 6., 6., 6.],
[ 4., 4., 4., 4., 4., 4., 4., 4., 4., 4.],
[ 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.],
[ 7., 7., 7., 7., 7., 7., 7., 7., 7., 7.]])

More Indexing Help


Indexing a 2d matrix can be a bit confusing at first, especially when you start to
add in step size. Try google image searching NumPy indexing to fins useful images,
like this one:

No description has been provided for this image


Selection
Let's briefly go over how to use brackets for selection based off of comparison
operators.

In [28]: arr = np.arange(1,11)


arr

Out[28]: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

In [30]: arr > 4

Out[30]: array([False, False, False, False, True, True, True, True, True, True],
dtype=bool)

In [31]: bool_arr = arr>4

In [32]: bool_arr

Out[32]: array([False, False, False, False, True, True, True, True, True, True],
dtype=bool)

In [33]: arr[bool_arr]

Out[33]: array([ 5, 6, 7, 8, 9, 10])

In [34]: arr[arr>2]

Out[34]: array([ 3, 4, 5, 6, 7, 8, 9, 10])

In [37]: x = 2
arr[arr>x]

Out[37]: array([ 3, 4, 5, 6, 7, 8, 9, 10])

Great Job!
No description has been provided for this image

NumPy Operations

Arithmetic
You can easily perform array with array arithmetic, or scalar with array arithmetic.
Let's see some examples:

In [1]: import numpy as np


arr = np.arange(0,10)

In [2]: arr + arr

Out[2]: array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])

In [3]: arr * arr

Out[3]: array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81])

In [4]: arr - arr

Out[4]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

In [5]: # Warning on division by zero, but not an error!


# Just replaced with nan
arr/arr

/Users/marci/anaconda/lib/python3.5/site-packages/ipykernel/__main__.py:1: Runt
imeWarning: invalid value encountered in true_divide
if __name__ == '__main__':
Out[5]: array([ nan, 1., 1., 1., 1., 1., 1., 1., 1., 1.])

In [6]: # Also warning, but not an error instead infinity


1/arr

/Users/marci/anaconda/lib/python3.5/site-packages/ipykernel/__main__.py:1: Runt
imeWarning: divide by zero encountered in true_divide
if __name__ == '__main__':
Out[6]: array([ inf, 1. , 0.5 , 0.33333333, 0.25 ,
0.2 , 0.16666667, 0.14285714, 0.125 , 0.11111111])

In [10]: arr**3
Out[10]: array([ 0, 1, 8, 27, 64, 125, 216, 343, 512, 729])

Universal Array Functions


Numpy comes with many universal array functions, which are essentially just
mathematical operations you can use to perform the operation across the array.
Let's show some common ones:

In [12]: #Taking Square Roots


np.sqrt(arr)

Out[12]: array([ 0. , 1. , 1.41421356, 1.73205081, 2. ,


2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. ])

In [13]: #Calcualting exponential (e^)


np.exp(arr)

Out[13]: array([ 1.00000000e+00, 2.71828183e+00, 7.38905610e+00,


2.00855369e+01, 5.45981500e+01, 1.48413159e+02,
4.03428793e+02, 1.09663316e+03, 2.98095799e+03,
8.10308393e+03])

In [14]: np.max(arr) #same as arr.max()

Out[14]: 9

In [15]: np.sin(arr)

Out[15]: array([ 0. , 0.84147098, 0.90929743, 0.14112001, -0.7568025 ,


-0.95892427, -0.2794155 , 0.6569866 , 0.98935825, 0.41211849])

In [16]: np.log(arr)

/Users/marci/anaconda/lib/python3.5/site-packages/ipykernel/__main__.py:1: Runt
imeWarning: divide by zero encountered in log
if __name__ == '__main__':
Out[16]: array([ -inf, 0. , 0.69314718, 1.09861229, 1.38629436,
1.60943791, 1.79175947, 1.94591015, 2.07944154, 2.19722458])

Great Job!
That's all we need to know for now!
No description has been provided for this image

NumPy Exercises - Solutions


Now that we've learned about NumPy let's test your knowledge. We'll start off with
a few simple tasks and then you'll be asked some more complicated questions.

Import NumPy as np

In [1]: import numpy as np

Create an array of 10 zeros

In [2]: np.zeros(10)

Out[2]: array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])

Create an array of 10 ones

In [3]: np.ones(10)

Out[3]: array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

Create an array of 10 fives

In [4]: np.ones(10) * 5

Out[4]: array([ 5., 5., 5., 5., 5., 5., 5., 5., 5., 5.])

Create an array of the integers from 10 to 50

In [5]: np.arange(10,51)

Out[5]: array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 50])

Create an array of all the even integers from 10 to 50

In [6]: np.arange(10,51,2)

Out[6]: array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42,
44, 46, 48, 50])
Create a 3x3 matrix with values ranging from 0 to 8

In [7]: np.arange(9).reshape(3,3)

Out[7]: array([[0, 1, 2],


[3, 4, 5],
[6, 7, 8]])

Create a 3x3 identity matrix

In [8]: np.eye(3)

Out[8]: array([[ 1., 0., 0.],


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

Use NumPy to generate a random number between 0 and 1

In [15]: np.random.rand(1)

Out[15]: array([ 0.42829726])

Use NumPy to generate an array of 25 random numbers sampled


from a standard normal distribution

In [33]: np.random.randn(25)

Out[33]: array([ 1.32031013, 1.6798602 , -0.42985892, -1.53116655, 0.85753232,


0.87339938, 0.35668636, -1.47491157, 0.15349697, 0.99530727,
-0.94865451, -1.69174783, 1.57525349, -0.70615234, 0.10991879,
-0.49478947, 1.08279872, 0.76488333, -2.3039931 , 0.35401124,
-0.45454399, -0.64754649, -0.29391671, 0.02339861, 0.38272124])

Create the following matrix:

In [35]: np.arange(1,101).reshape(10,10) / 100


Out[35]: array([[ 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.1
],
[ 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.2
],
[ 0.21, 0.22, 0.23, 0.24, 0.25, 0.26, 0.27, 0.28, 0.29, 0.3
],
[ 0.31, 0.32, 0.33, 0.34, 0.35, 0.36, 0.37, 0.38, 0.39, 0.4
],
[ 0.41, 0.42, 0.43, 0.44, 0.45, 0.46, 0.47, 0.48, 0.49, 0.5
],
[ 0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58, 0.59, 0.6
],
[ 0.61, 0.62, 0.63, 0.64, 0.65, 0.66, 0.67, 0.68, 0.69, 0.7
],
[ 0.71, 0.72, 0.73, 0.74, 0.75, 0.76, 0.77, 0.78, 0.79, 0.8
],
[ 0.81, 0.82, 0.83, 0.84, 0.85, 0.86, 0.87, 0.88, 0.89, 0.9
],
[ 0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1.
]])

Create an array of 20 linearly spaced points between 0 and 1:

In [36]: np.linspace(0,1,20)

Out[36]: array([ 0. , 0.05263158, 0.10526316, 0.15789474, 0.21052632,


0.26315789, 0.31578947, 0.36842105, 0.42105263, 0.47368421,
0.52631579, 0.57894737, 0.63157895, 0.68421053, 0.73684211,
0.78947368, 0.84210526, 0.89473684, 0.94736842, 1. ])

Numpy Indexing and Selection


Now you will be given a few matrices, and be asked to replicate the resulting
matrix outputs:

In [38]: mat = np.arange(1,26).reshape(5,5)


mat

Out[38]: array([[ 1, 2, 3, 4, 5],


[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25]])

In [39]: # WRITE CODE HERE THAT REPRODUCES THE OUTPUT OF THE CELL BELOW
# BE CAREFUL NOT TO RUN THE CELL BELOW, OTHERWISE YOU WON'T
# BE ABLE TO SEE THE OUTPUT ANY MORE

In [40]: mat[2:,1:]
Out[40]: array([[12, 13, 14, 15],
[17, 18, 19, 20],
[22, 23, 24, 25]])

In [29]: # WRITE CODE HERE THAT REPRODUCES THE OUTPUT OF THE CELL BELOW
# BE CAREFUL NOT TO RUN THE CELL BELOW, OTHERWISE YOU WON'T
# BE ABLE TO SEE THE OUTPUT ANY MORE

In [41]: mat[3,4]

Out[41]: 20

In [30]: # WRITE CODE HERE THAT REPRODUCES THE OUTPUT OF THE CELL BELOW
# BE CAREFUL NOT TO RUN THE CELL BELOW, OTHERWISE YOU WON'T
# BE ABLE TO SEE THE OUTPUT ANY MORE

In [42]: mat[:3,1:2]

Out[42]: array([[ 2],


[ 7],
[12]])

In [31]: # WRITE CODE HERE THAT REPRODUCES THE OUTPUT OF THE CELL BELOW
# BE CAREFUL NOT TO RUN THE CELL BELOW, OTHERWISE YOU WON'T
# BE ABLE TO SEE THE OUTPUT ANY MORE

In [46]: mat[4,:]

Out[46]: array([21, 22, 23, 24, 25])

In [32]: # WRITE CODE HERE THAT REPRODUCES THE OUTPUT OF THE CELL BELOW
# BE CAREFUL NOT TO RUN THE CELL BELOW, OTHERWISE YOU WON'T
# BE ABLE TO SEE THE OUTPUT ANY MORE

In [49]: mat[3:5,:]

Out[49]: array([[16, 17, 18, 19, 20],


[21, 22, 23, 24, 25]])

Now do the following

Get the sum of all the values in mat

In [50]: mat.sum()

Out[50]: 325
Get the standard deviation of the values in mat

In [51]: mat.std()

Out[51]: 7.2111025509279782

Get the sum of all the columns in mat

In [53]: mat.sum(axis=0)

Out[53]: array([55, 60, 65, 70, 75])

Great Job!

You might also like