NumPy 2
NumPy 2
Computing
The basics
In [2]:
import numpy as np
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
In [4]:
type(squares)
numpy.ndarray
Out[4]:
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)
<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)]
print(a.ndim)
print(b.ndim)
2
3
In [14]:
odds = list(i for i in range(10) if i%2 != 0)
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
In [17]:
b = np.linspace(0, 1, 100) # create array of 100 values between 0 and 1
b
In [18]:
from numpy import pi
f = np.sin(c)
f
In [19]:
# creating an array from a function
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
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
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)
print(mult, end='\n\n')
print(dot_prod1, end='\n\n')
print(dot_prod2)
[[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
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)
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
[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')
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
[[ 1 8 27]
[ 64 125 216]
[ 343 512 729]
[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)
1,4,9,16,25,
In [36]:
# Advanced: using ... for axis completion
A = np.arange(125).reshape(5, 5, 5) + 1
[[ 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
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)))
[[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
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))
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
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]])
In [49]:
# use hsplit or vsplit to split arrays
a = np.ones(9).reshape(3, 3)
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.]]
In [50]:
a = np.arange(15).reshape(5, 3)
b = a
a is b
True
Out[50]:
print('a is b:', a is b)
print('a is b.base:', a is b.base)
b.shape = 3, 2
b[0, 1] = 1000
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)
a is b: False