0% found this document useful (0 votes)
20 views11 pages

NumPy 2

Intermediate Numpy

Uploaded by

mananbarwal2
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)
20 views11 pages

NumPy 2

Intermediate Numpy

Uploaded by

mananbarwal2
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/ 11

NumPy: A Python Library for Scientific

Computing
The basics
In [2]:
import numpy as np

a = np.arange(15).reshape(3, 5) # Creates a 3x5 NumPy array with values in [0, 14]


a

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

In [3]:
squares = np.array([x**2 for x in range(10)])
squares

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


Out[3]:

In [4]:
type(squares)

numpy.ndarray
Out[4]:

Useful n-dimensional array (np.array) methods

In [5]:
a.shape

(3, 5)
Out[5]:

In [6]:
a.ndim

2
Out[6]:

In [7]:
a.dtype.name

'int32'
Out[7]:

In [8]:
a.itemsize

4
Out[8]:

In [9]:
a.size

15
Out[9]:

In [10]:
type(a)

numpy.ndarray
Out[10]:
Creating arrays from Python's sequence types

In [11]:
squares = [x**2 for x in range(10)] # python list
cubes = tuple(x**3 for x in range(10)) # python tuple
evens = {x for x in range(10) if x%2 == 0} # python set

print(type(squares))
print(type(cubes))
print(type(evens))

<class 'list'>
<class 'tuple'>
<class 'set'>

In [12]:
a = np.array(squares)
b = np.array(cubes)
c = np.array(evens)

if type(a) == type(b) == type(c):


print(type(a))

<class 'numpy.ndarray'>

In [13]:
seq2 = [[x, x**2, x**3] for x in range(10)]
seq3 = [[[x for x in range(3)], [y for y in range(3, 6)]] for z in range(10)]

a = np.array(seq2) # create array from nested lists of depth 2


b = np.array(seq3) # create array from nested lists of depth 3

print(a.ndim)
print(b.ndim)

2
3

In [14]:
odds = list(i for i in range(10) if i%2 != 0)

numpy_odds = np.array(odds, dtype=complex) # declare data type during instantiation


numpy_odds

array([1.+0.j, 3.+0.j, 5.+0.j, 7.+0.j, 9.+0.j])


Out[14]:

In [15]:
zeros = np.zeros((3, 3), dtype=np.int32) # create a 3x3 array of 0's
ones = np.ones((2, 2), dtype=np.float64) # create a 2x2 array of 1's
empty = np.empty((3, 3))

print(zeros, zeros.dtype.name)
print(ones, ones.dtype.name)
print(empty, empty.dtype.name)

[[0 0 0]
[0 0 0]
[0 0 0]] int32
[[1. 1.]
[1. 1.]] float64
[[0.00000000e+000 0.00000000e+000 0.00000000e+000]
[0.00000000e+000 0.00000000e+000 8.35959073e-321]
[1.37962117e-306 0.00000000e+000 0.00000000e+000]] float64
In [16]:
a = np.arange(5, 30, 5) # create array from range [5, 30) with step of 5
a

array([ 5, 10, 15, 20, 25])


Out[16]:

In [17]:
b = np.linspace(0, 1, 100) # create array of 100 values between 0 and 1
b

array([0. , 0.01010101, 0.02020202, 0.03030303, 0.04040404,


Out[17]:
0.05050505, 0.06060606, 0.07070707, 0.08080808, 0.09090909,
0.1010101 , 0.11111111, 0.12121212, 0.13131313, 0.14141414,
0.15151515, 0.16161616, 0.17171717, 0.18181818, 0.19191919,
0.2020202 , 0.21212121, 0.22222222, 0.23232323, 0.24242424,
0.25252525, 0.26262626, 0.27272727, 0.28282828, 0.29292929,
0.3030303 , 0.31313131, 0.32323232, 0.33333333, 0.34343434,
0.35353535, 0.36363636, 0.37373737, 0.38383838, 0.39393939,
0.4040404 , 0.41414141, 0.42424242, 0.43434343, 0.44444444,
0.45454545, 0.46464646, 0.47474747, 0.48484848, 0.49494949,
0.50505051, 0.51515152, 0.52525253, 0.53535354, 0.54545455,
0.55555556, 0.56565657, 0.57575758, 0.58585859, 0.5959596 ,
0.60606061, 0.61616162, 0.62626263, 0.63636364, 0.64646465,
0.65656566, 0.66666667, 0.67676768, 0.68686869, 0.6969697 ,
0.70707071, 0.71717172, 0.72727273, 0.73737374, 0.74747475,
0.75757576, 0.76767677, 0.77777778, 0.78787879, 0.7979798 ,
0.80808081, 0.81818182, 0.82828283, 0.83838384, 0.84848485,
0.85858586, 0.86868687, 0.87878788, 0.88888889, 0.8989899 ,
0.90909091, 0.91919192, 0.92929293, 0.93939394, 0.94949495,
0.95959596, 0.96969697, 0.97979798, 0.98989899, 1. ])

In [18]:
from numpy import pi

c = np.linspace(0, 2*pi, 10) # useful for evaluating trigonometric function at point

f = np.sin(c)
f

array([ 0.00000000e+00, 6.42787610e-01, 9.84807753e-01, 8.66025404e-01,


Out[18]:
3.42020143e-01, -3.42020143e-01, -8.66025404e-01, -9.84807753e-01,
-6.42787610e-01, -2.44929360e-16])

In [19]:
# creating an array from a function

def f(row_num, col_num):


return 2*row_num + col_num

F = np.fromfunction(f, (3, 3), dtype=int)


F

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

Printing arrays

In [20]:
dim1 = np.arange(15) # Create 1 1x15 matrix; n=1
dim2 = np.arange(15).reshape(3, 5) # Create 1 3x5 matrix; n=2
dim3 = np.arange(24).reshape(2, 3, 4) # Create 2 3x4 matrices; n=3

print(dim1, end='\t[1x15]\n\n')
print(dim2, end='\t[3x5]\n\n')
print(dim3, end='\t[2x3x4]')

[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] [1x15]

[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]] [3x5]

[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]

[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]] [2x3x4]

In [21]:
very_large = np.arange(10000).reshape(100, 100)
print(very_large) # printing a very large array

[[ 0 1 2 ... 97 98 99]
[ 100 101 102 ... 197 198 199]
[ 200 201 202 ... 297 298 299]
...
[9700 9701 9702 ... 9797 9798 9799]
[9800 9801 9802 ... 9897 9898 9899]
[9900 9901 9902 ... 9997 9998 9999]]
Common NumPy array operations

- Arithmetic operators on arrays apply elementwise.


- A new array is created and filled with the result.

In [22]:
a = np.arange(10)
b = np.array([2 for x in range(10)])
c = np.ones(10, dtype=int)
result = a + b - c # add 2 and subtract 1 from each element of a

print(result)

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

In [23]:
result **= 2 # square each element of result
result

array([ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100])


Out[23]:

In [24]:
result < 10

array([ True, True, True, False, False, False, False, False, False,
Out[24]:
False])

In [25]:
a = np.ones(15).reshape(3, 5)
b = np.ones(15).reshape(5, 3)

mult = a * 10 # element-wise multiplication


dot_prod1 = a.dot(b) # dot product version 1
dot_prod2 = np.dot(a, b) # dot product version 2

print(mult, end='\n\n')
print(dot_prod1, end='\n\n')
print(dot_prod2)

[[10. 10. 10. 10. 10.]


[10. 10. 10. 10. 10.]
[10. 10. 10. 10. 10.]]

[[5. 5. 5.]
[5. 5. 5.]
[5. 5. 5.]]

[[5. 5. 5.]
[5. 5. 5.]
[5. 5. 5.]]

In [26]:
a, b = dot_prod1, dot_prod2

a += b # += and *= act in place -- they modify the existing array


a

array([[10., 10., 10.],


Out[26]:
[10., 10., 10.],
[10., 10., 10.]])

In [27]:
# array operations result in upcasting (result is more general type)
a = np.ones(10, dtype=int)
b = np.ones(10, dtype=float)
c = np.ones(10, dtype=complex)

a_plus_b = a + b # int + float


b_plus_c = b + c # float + complex

print(a_plus_b.dtype.name)
print(b_plus_c.dtype.name)

float64
complex128

In [28]:
# useful array methods
a = np.arange(1, 11)
print('Sum:', a.sum())
print('Min:', a.min())
print('Max:', a.max())

Sum: 55
Min: 1
Max: 10

In [29]:
# applying methods to a single axis
a = np.arange(15).reshape(3, 5) + 1

print(a.sum(axis=0)) # sum each column


print(a.min(axis=1)) # min of each row
a

[18 21 24 27 30]
[ 1 6 11]
array([[ 1, 2, 3, 4, 5],
Out[29]:
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]])

Universal functions
In [30]:
# universal functions (sin, cos, exp, sqrt, ... etc)
a = np.linspace(0, 2*pi, 10000)

sin_a = np.sin(a)
sqrt_a = np.sqrt(a)
exp_a = np.exp(a)

print(sin_a, end='\n\n')
print(sqrt_a, end='\n\n')
print(exp_a, end='\n\n')

[ 0.00000000e+00 6.28381328e-04 1.25676241e-03 ... -1.25676241e-03


-6.28381328e-04 -2.44929360e-16]

[0. 0.02506754 0.03545085 ... 2.50637757 2.50650293 2.50662827]

[ 1. 1.00062858 1.00125755 ... 534.81909228 535.15526825


535.49165552]

Indexing, slicing, and iterating

In [31]:
# indexing elements from multidimensional arrays
A = np.array([x**2 for x in range(1, 11)]).reshape(2, 5)

print(A, end='\n\n')
print('A[0]\t\t', A[0])
print('A[-1]\t\t', A[-1])
print('A[0][0]\t\t', A[0][0])
print('A[-1][-1]\t', A[-1][-1])
#print('', A[])

[[ 1 4 9 16 25]
[ 36 49 64 81 100]]

A[0] [ 1 4 9 16 25]
A[-1] [ 36 49 64 81 100]
A[0][0] 1
A[-1][-1] 100

In [32]:
# slicing NumPy arrays
cubes = np.arange(1, 13).reshape(4, 3)**3 # cubes of 1-12

print(cubes[:,:], end='\n\n') # all rows, all cols


print('First Column:\t', cubes[:, 0]) # first col
print('Last Column:\t', cubes[:, -1]) # last col
print('First Row:\t', cubes[0, :]) # first row
print('Last Row:\t', cubes[-1, :]) # last row

[[ 1 8 27]
[ 64 125 216]
[ 343 512 729]
[1000 1331 1728]]

First Column: [ 1 64 343 1000]


Last Column: [ 27 216 729 1728]
First Row: [ 1 8 27]
Last Row: [1000 1331 1728]

In [33]:
# iterating through array elements
A = np.array([x+1 for x in range(10)])
A

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

In [34]:
for a in A:
print(a, end=',')

1,2,3,4,5,6,7,8,9,10,

In [35]:
A = A.reshape(2, 5)

for a in A[0,:]: # for element in row 1


print(a**2, end=',')

1,4,9,16,25,

In [36]:
# Advanced: using ... for axis completion
A = np.arange(125).reshape(5, 5, 5) + 1

print('A[0, ...] == A[0, :, :]', end='\n\n')


print(A[0, ...], '\n\n', A[0, :, :])

A[0, ...] == A[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 25]]

[[ 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 [37]:
# flattening a 5x5x5 array for iteration
for a in A.flat:
print(a, end=',')

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,26,27,28,29,30,31,3
2,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,6
0,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,8
8,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,11
2,113,114,115,116,117,118,119,120,121,122,123,124,125,

Shape manipulation
Changing the shape of an array

In [38]:
a = np.floor(10*np.random.random((3, 4)))
print(a)
print(a.shape)

[[8. 2. 9. 3.]
[1. 3. 3. 1.]
[7. 2. 3. 4.]]
(3, 4)

In [39]:
a.ravel() # returns a COPY of the array flattened
array([8., 2., 9., 3., 1., 3., 3., 1., 7., 2., 3., 4.])
Out[39]:

In [40]:
a.reshape(6, 2) # returns a COPY of the array reshaped

array([[8., 2.],
Out[40]:
[9., 3.],
[1., 3.],
[3., 1.],
[7., 2.],
[3., 4.]])

In [41]:
a.T # returns a COPY of the array, transposed

array([[8., 1., 7.],


Out[41]:
[2., 3., 2.],
[9., 3., 3.],
[3., 1., 4.]])

In [42]:
print('A:\t', a.shape)
print('A^T:\t', a.T.shape)

A: (3, 4)
A^T: (4, 3)

In [43]:
A = np.floor(10*np.random.random((3, 4)))

A.reshape(4, 3) # reshape returns a COPY of A


print(A, 'array A remains unchanged')

A.resize(4, 3) # resize modifies array A


print(A, 'array A is of a new shape')

[[3. 8. 3. 8.]
[5. 8. 2. 0.]
[4. 4. 0. 2.]] array A remains unchanged
[[3. 8. 3.]
[8. 5. 8.]
[2. 0. 4.]
[4. 0. 2.]] array A is of a new shape

Stacking NumPy arrays horizontally and vertically

In [44]:
a = np.zeros(9, dtype=int).reshape(3, 3)
b = np.ones(9, dtype=int).reshape(3, 3)

# stack horizontally:
hor = np.hstack((a, b))
ver = np.vstack((a, b))

print('a:\n', a)
print('b:\n', b)
print('Horizontal Stack:\n', hor)
print('Vertical Stack:\n', ver)

a:
[[0 0 0]
[0 0 0]
[0 0 0]]
b:
[[1 1 1]
[1 1 1]
[1 1 1]]
Horizontal Stack:
[[0 0 0 1 1 1]
[0 0 0 1 1 1]
[0 0 0 1 1 1]]
Vertical Stack:
[[0 0 0]
[0 0 0]
[0 0 0]
[1 1 1]
[1 1 1]
[1 1 1]]

In [45]:
# similarly, row_stack and column_stack can be used to stack into 2D arrays
r_stack = np.row_stack((a, b))
c_stack = np.column_stack((a, b))

print('Horizontal Stack:\n', hor)


print('Vertical Stack:\n', ver)
print('Column Stack:\n', c_stack)
print('Row Stack:\n', r_stack)

Horizontal Stack:
[[0 0 0 1 1 1]
[0 0 0 1 1 1]
[0 0 0 1 1 1]]
Vertical Stack:
[[0 0 0]
[0 0 0]
[0 0 0]
[1 1 1]
[1 1 1]
[1 1 1]]
Column Stack:
[[0 0 0 1 1 1]
[0 0 0 1 1 1]
[0 0 0 1 1 1]]
Row Stack:
[[0 0 0]
[0 0 0]
[0 0 0]
[1 1 1]
[1 1 1]
[1 1 1]]

In [46]:
from numpy import newaxis

r_stack = np.row_stack((a[newaxis], b[newaxis]))


c_stack = np.column_stack((a[newaxis], b[newaxis]))

print('Column Stack:\n', c_stack)


print('Row Stack:\n', r_stack)

Column Stack:
[[[0 0 0]
[0 0 0]
[0 0 0]
[1 1 1]
[1 1 1]
[1 1 1]]]
Row Stack:
[[[0 0 0]
[0 0 0]
[0 0 0]]

[[1 1 1]
[1 1 1]
[1 1 1]]]

In [47]:
# use range literals to concatenate arrays on the fly
np.r_[1:5, 5, 6:10, 10]

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

In [48]:
np.c_[1:5]

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

Splitting large arrays into smaller ones

In [49]:
# use hsplit or vsplit to split arrays
a = np.ones(9).reshape(3, 3)

a_1, a_2, a_3 = np.hsplit(a, 3) # split a into 3 arrays

print(a, end='\n\n')
print(a_1, end='\n\n')
print(a_2, end='\n\n')
print(a_3, end='\n\n')

[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]

[[1.]
[1.]
[1.]]

[[1.]
[1.]
[1.]]

[[1.]
[1.]
[1.]]

Views and copies


No copy at all

In [50]:
a = np.arange(15).reshape(5, 3)
b = a
a is b

True
Out[50]:

View or shallow copy


In [51]:
# use the view() method to create a shallow copy of an array
a = np.array([x**2 for x in range(6)])
b = a.view()

print('a is b:', a is b)
print('a is b.base:', a is b.base)

b.shape = 3, 2

print(a.shape, ': no change to a\'s shape') # a's shape doesn't change

b[0, 1] = 1000

print(a, 'a\'s data has changed!')

a is b: False
a is b.base: True
(6,) : no change to a's shape
[ 0 1000 4 9 16 25] a's data has changed!

Deep copy

In [52]:
a = np.array([x+1 for x in range(10)])
b = a.copy()

print('a:', a, end='\t(Original)\n\n')
print('b:', b, end='\t(Deep Copy)\n\n')
print('a is b:', a is b)

a: [ 1 2 3 4 5 6 7 8 9 10] (Original)

b: [ 1 2 3 4 5 6 7 8 9 10] (Deep Copy)

a is b: False

You might also like