Python NumPy Quick Introduction

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. Maybe you will get a habit of using numpy arrays instead of python lists.

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.

Creating NumPy Arrays

From a Python List

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

my_list = [1,2,3]
np.array(my_list)
my_matrix = [[1,2,3],[4,5,6],[7,8,9]]
np.array(my_matrix)
output: array([[1, 2, 3],
               [4, 5, 6],
               [7, 8, 9]])

It is that simple!

Most Useful and General Methods

There are lots of built-in ways to generate Arrays

arange

Return evenly spaced values within a given interval.

np.arange(0,10) # inclusive start, exclusive stop
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.arange(0,11,2) # Step size 2
array([ 0,  2,  4,  6,  8, 10])

zeros and ones

Generate arrays of zeros or ones

np.zeros(3)
array([ 0.,  0.,  0.])
np.zeros((5,5))
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.]])
np.ones(3)
array([ 1.,  1.,  1.])
np.ones((3,3)
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])

linspace

Return evenly spaced numbers over a specified interval.

np.linspace(0, 10, 3)
array([  0.,   5.,  10.])
np.linspace(0, 10, 51) # 51 items at the result
array([  0. ,   0.2,   0.4,   0.6,   0.8,   1. ,   1.2,   1.4,   1.6,
         1.8,   2. ,   2.2,   2.4,   2.6,   2.8,   3. ,   3.2,   3.4,
         3.6,   3.8,   4. ,   4.2,   4.4,   4.6,   4.8,   5. ,   5.2,
         5.4,   5.6,   5.8,   6. ,   6.2,   6.4,   6.6,   6.8,   7. ,
         7.2,   7.4,   7.6,   7.8,   8. ,   8.2,   8.4,   8.6,   8.8,
         9. ,   9.2,   9.4,   9.6,   9.8,  10. ])

eye

Creates an identity matrix

np.eye(4)
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).

np.random.rand(2)
array([ 0.11570539,  0.35279769])
np.random.rand(5,5)
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:

np.random.randn(2)
array([-0.27954018,  0.90078368])
np.random.randn(5,5)
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).

np.random.randint(1,100)
44
np.random.randint(1,100,10)
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:

arr = np.arange(25)
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])
ranarr = np.random.randint(0,50,10)
ranarr
array([10, 12, 41, 17, 49,  2, 46,  3, 19, 39])

Reshape

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

arr.reshape(5,5)
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

ranarr
array([10, 12, 41, 17, 49,  2, 46,  3, 19, 39]
ranarr.max()
49
ranarr.argmax()
4
ranarr.min()
2
ranarr.argmin()
5

Shape

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

Vector

arr.shape
(25,)

Notice the two sets of brackets

arr.reshape(1,25)
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]])
arr.reshape(1,25).shape
(1, 25)
arr.reshape(25,1)
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]])
arr.reshape(25,1).shape
(25, 1)

dtype

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

arr.dtype
dtype('int64')

NumPy Indexing and Selection

Now we will discuss how to select elements or groups of elements from an array.

Creating sample array

arr = np.arange(0,11)
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:

Get a value at an index

arr[8]
8

Get values in a range (second is exclusive meaning exactly [second – first] items)

arr[1:5]
array([1, 2, 3, 4])

Get values in a range

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

Broadcasting

Numpy arrays differ from a normal Python list because of their ability to broadcast:Setting a value with index range (Broadcasting)

arr[0:5]=100
array([100, 100, 100, 100, 100,   5,   6,   7,   8,   9,  10])
Reset array, we’ll see why I had to reset in a moment
arr = np.arange(0,11)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10])

Important notes on Slices: Any change on slice will affect on the original array!!!

slice_of_arr = arr[0:6]
array([0, 1, 2, 3, 4, 5])
Change Slice
slice_of_arr[:]=99
array([99, 99, 99, 99, 99, 99])

Now note the changes also occur in our original array!

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!

To get a copy, need to be explicit

arr_copy = arr.copy()
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].

Comma notation is more clear.

arr_2d = np.array(([5,10,15],[20,25,30],[35,40,45]))
array([[ 5, 10, 15],
       [20, 25, 30],
       [35, 40, 45]])
# Indexing row
arr_2d[1]
array([20, 25, 30])

Getting individual element value

arr_2d[1][0] or arr_2d[1,0]
20

2D array slicing. Shape (2,2) from top right corner

arr_2d[:2,1:]
array([[10, 15],
       [25, 30]])
 Shape bottom row
arr_2d[2] or arr_2d[2,:]
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:

Set up matrix

arr2d = np.zeros((10,10))

Length of array

arr_length = arr2d.shape[1]

Set up array

for i in range(arr_length):
    arr2d[i] = i
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

arr2d[[2,4,6,8]]
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.]])
 Allows in any order
arr2d[[6,4,2,7]]
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. Here is a useful image representing the indexing logic.

Selection

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

arr = np.arange(1,11)
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10])
bool_arr = arr > 4
array([False, False, False, False,  True,  True,  True,  True,  True,  True], dtype=bool)
arr[bool_arr] # to get back the original array values
array([ 5,  6,  7,  8,  9, 10])
arr[arr>2]
array([ 3,  4,  5,  6,  7,  8,  9, 10])

NumPy Operations

Arithmetic

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

arr = np.arange(0,10)
arr + arr
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
arr * arr
array([ 0,  1,  4,  9, 16, 25, 36, 49, 64, 81])
arr - arr
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
 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: RuntimeWarning: invalid value encountered in true_divide
  if __name__ == '__main__':
array([ nan,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.,   1.])
 Also warning, but not an error instead infinity
1/arr
/Users/marci/anaconda/lib/python3.5/site-packages/ipykernel/__main__.py:1: RuntimeWarning: divide by zero encountered in true_divide
  if __name__ == '__main__':
array([        inf,  1.        ,  0.5       ,  0.33333333,  0.25      ,
        0.2       ,  0.16666667,  0.14285714,  0.125     ,  0.11111111])
arr**3
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:

Taking Square Roots
np.sqrt(arr)
array([ 0.        ,  1.        ,  1.41421356,  1.73205081,  2.        ,
        2.23606798,  2.44948974,  2.64575131,  2.82842712,  3.        ])

Calcualting exponential

np.exp(arr)
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])
np.max(arr) #same as arr.max()
9
np.sin(arr)
array([ 0.        ,  0.84147098,  0.90929743,  0.14112001, -0.7568025 ,
       -0.95892427, -0.2794155 ,  0.6569866 ,  0.98935825,  0.41211849])
np.log(arr)
/Users/marci/anaconda/lib/python3.5/site-packages/ipykernel/__main__.py:1: RuntimeWarning: divide by zero encountered in log
  if __name__ == '__main__':
array([       -inf,  0.        ,  0.69314718,  1.09861229,  1.38629436,
        1.60943791,  1.79175947,  1.94591015,  2.07944154,  2.19722458])

NumPy Quick Recap

Create an array of 10 fives

np.ones(10) * 5
array([ 5.,  5.,  5.,  5.,  5.,  5.,  5.,  5.,  5.,  5.])

Create an array of the integers from 10 to 50

np.arange(10,51)
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

np.arange(10,51,2)
array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42,
       44, 46, 48, 50])

Create a 3×3 matrix with values ranging from 0 to 8

np.arange(9).reshape(3,3)
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

Create a 3×3 identity matrix

np.eye(3)
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])

Use NumPy to generate a random number between 0 and 1

np.random.rand(1)
array([ 0.42829726])

Use NumPy to generate an array of 25 random numbers sampled from a standard normal distribution

np.random.randn(25)
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:

np.arange(1,101).reshape(10,10) / 100
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:

np.linspace(0,1,21)
array([ 0.  ,  0.05,  0.1 ,  0.15,  0.2 ,  0.25,  0.3 ,  0.35,  0.4 ,
        0.45,  0.5 ,  0.55,  0.6 ,  0.65,  0.7 ,  0.75,  0.8 ,  0.85,
        0.9 ,  0.95,  1.  ])

Indexing and Selection

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

mat = np.arange(1,26).reshape(5,5)
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]])
mat[2:,1:]
array([[12, 13, 14, 15],
       [17, 18, 19, 20],
       [22, 23, 24, 25]])
mat[:3,1:3]
array([[ 2,  3],
       [ 7,  8],
       [12, 13]])
mat[4,:]
array([21, 22, 23, 24, 25])
mat[3:5,:]
array([[16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25]])

Now do the following

Get the sum of all the values in mat

mat.sum()
325

Get the standard deviation of the values in mat

mat.std()
7.2111025509279782

Get the sum of all the columns in mat

mat.sum(axis=0)
array([55, 60, 65, 70, 75])

 

 

 

 

 

Reklamlar

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s