Basics#
# importing numpy
import numpy as np
NumPy arrays#
a = np.array( [0, 1, 2, 3] )
# standard Python list
b = [0, 1, 2, 3]
print( a )
print( b )
[0 1 2 3]
[0, 1, 2, 3]
print( type(a) )
print( type(b) )
<class 'numpy.ndarray'>
<class 'list'>
print( a.ndim )
print( a.shape )
print( a.size )
1
(4,)
4
# define 2D array
a = np.array( [ [1, 2, 3],
[4, 5, 6] ] )
print( a )
[[1 2 3]
[4 5 6]]
print( a.ndim )
print( a.shape )
print( a.size )
2
(2, 3)
6
# iterating
for c in a:
print( c )
[1 2 3]
[4 5 6]
Functions for creating arrays#
# evenly spaced with step size
a = np.arange(1, 10, 2) # start, end (exclusive), step size
print( a )
[1 3 5 7 9]
# evenly spaced with number of steps
a = np.linspace(1, 9, 5) # start, end (inclusive), number of steps
print( a )
[1. 3. 5. 7. 9.]
# log-spaced
a = np.logspace(1, 4, 4)
print( a )
[ 10. 100. 1000. 10000.]
# all ones
a = np.ones((2, 3))
print( a )
[[1. 1. 1.]
[1. 1. 1.]]
# all zeros
a = np.zeros((3, 3))
print( a )
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
# diagonal one
a = np.eye(3)
print( a )
print( np.diag(a) )
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
[1. 1. 1.]
# self-defined diagonal
a = np.diag( np.array([1,2,3]) )
print( a )
[[1 0 0]
[0 2 0]
[0 0 3]]
# using a self-defined function
def myfunc(i, j):
return i*10 + j
a = np.fromfunction(myfunc, (3,3))
print(a)
[[ 0. 1. 2.]
[10. 11. 12.]
[20. 21. 22.]]
Data types#
int, float, complex, bool, string, etc. …
# integer
a = np.array([1, 2, 3], dtype=int)
print( a )
print( a.dtype )
[1 2 3]
int64
# float
a = np.array([1, 2, 3], dtype=float)
print( a )
print( a.dtype )
[1. 2. 3.]
float64
# complex
a = np.array([1, 2, 3], dtype=complex)
print( a )
print( a.dtype )
[1.+0.j 2.+0.j 3.+0.j]
complex128
Accessing Elements#
a = np.diag( np.linspace(1, 6, 3) )
print( a )
[[1. 0. 0. ]
[0. 3.5 0. ]
[0. 0. 6. ]]
print( a[2, 2] )
6.0
print( a[:, 0] )
[1. 0. 0.]
print( a[2, :] )
[0. 0. 6.]
a[2, 0] = 10.
print( a )
[[ 1. 0. 0. ]
[ 0. 3.5 0. ]
[10. 0. 6. ]]
print( a[:, 0] )
[ 1. 0. 10.]
print( a[2, :] )
[10. 0. 6.]
Slicing#
a = np.arange(10)
print( a )
[0 1 2 3 4 5 6 7 8 9]
print( a[5:] )
[5 6 7 8 9]
print( a[5:7] )
[5 6]
print( a[2:10:2] )
[2 4 6 8]
print( a[::-1] )
[9 8 7 6 5 4 3 2 1 0]
print( a[ [2,5] ] )
[2 5]
Reshaping, Stacking, Concatenating#
# standard 1D array
a = np.arange(0, 12)
print( a )
[ 0 1 2 3 4 5 6 7 8 9 10 11]
# create a 2D array out of an 1D one
a = np.arange(0, 12).reshape(3, 4)
print( a )
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
# create a 3D array out of an 1D one
a = np.arange(0, 12).reshape(3, 2, 2)
print( a )
[[[ 0 1]
[ 2 3]]
[[ 4 5]
[ 6 7]]
[[ 8 9]
[10 11]]]
# transposing
a = np.arange(0, 12).reshape(3,4)
print( a )
print( np.transpose( a ) )
print( a.T )
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
[[ 0 4 8]
[ 1 5 9]
[ 2 6 10]
[ 3 7 11]]
Stacking (easy concatenation)#
a = np.arange(0, 4).reshape(2,2)
b = np.arange(4, 8).reshape(2,2)
print( a )
print( b )
[[0 1]
[2 3]]
[[4 5]
[6 7]]
# vertical stack
c = np.vstack( (a, b) )
print( c )
[[0 1]
[2 3]
[4 5]
[6 7]]
# horizontal stack
c = np.hstack( (a, b) )
print( c )
[[0 1 4 5]
[2 3 6 7]]
Concatenating#
a = np.arange(0, 4).reshape(2, 2)
b = np.arange(4, 8).reshape(2, 2)
print( a )
print( b )
[[0 1]
[2 3]]
[[4 5]
[6 7]]
# vertical stack
c = np.concatenate((a, b), axis=0)
print( c )
[[0 1]
[2 3]
[4 5]
[6 7]]
# horizontal stack
c = np.concatenate((a, b), axis=1)
print( c )
[[0 1 4 5]
[2 3 6 7]]
Element-wise Operations#
Numerical Operations#
# define array
a = np.array( [0, 0.5, 1.0, 1.5, 2.0] )
print( a )
[0. 0.5 1. 1.5 2. ]
# subtract a float
print( a - 1.0 )
[-1. -0.5 0. 0.5 1. ]
# square all elements
print( a**2 )
[0. 0.25 1. 2.25 4. ]
# calculate sin of all elements
print( np.cos(a * np.pi) )
[ 1.0000000e+00 6.1232340e-17 -1.0000000e+00 -1.8369702e-16
1.0000000e+00]
# calculate exp of all elements
print( np.exp(a) )
[1. 1.64872127 2.71828183 4.48168907 7.3890561 ]
# calculate sqrt of all elements
print( np.sqrt(a) )
[0. 0.70710678 1. 1.22474487 1.41421356]
Numpy Timings!#
# with Numpy
a = np.arange(10000)
%timeit b = a**2.0
21.8 μs ± 197 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
# without Numpy
a = range(10000)
%timeit b = [ i**2.0 for i in a ]
1.96 ms ± 10.8 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
Comparisons / Conditional Operators#
# define array
a = np.array( [1, 2, 3, 4] )
# compare each element with a single number
print( a == 2 )
[False True False False]
b = np.array( [1, 0, 3, 7])
# compare arrays element-wise
print( a == b )
[ True False True False]
# compare arrays element-wise
print( a < b )
[False False False True]
Basic Reductions#
# create a 2D array
a = np.arange(0, 12).reshape(3, 4)
print( a )
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
# over-all sum
print( np.sum(a) )
66
# row / col-wise sums
print( np.sum(a, axis=0) )
print( np.sum(a, axis=1) )
[12 15 18 21]
[ 6 22 38]
# find global min / max
print( np.min(a) )
print( np.max(a) )
0
11
# row / col-wise min/max
print( np.min(a, axis=0) )
print( np.min(a, axis=1) )
[0 1 2 3]
[0 4 8]
# get indices of the corresponding min / max
a = np.array([1,6,-3,0,-7,5])
print( a )
[ 1 6 -3 0 -7 5]
print( np.argmin(a) )
4
print( np.argmax(a) )
1
Sorting#
a = np.array([[4, 3, 1],
[1, 2, 5]])
print( a )
[[4 3 1]
[1 2 5]]
# sort col-wise
print( np.sort(a, axis=0) )
[[1 2 1]
[4 3 5]]
# sort row-wise
print( np.sort(a, axis=1) )
[[1 3 4]
[1 2 5]]
Searching#
# select just some specific data
a = np.linspace(1, 10, 19)
print( a )
[ 1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. 5.5 6. 6.5 7. 7.5
8. 8.5 9. 9.5 10. ]
# find indices for a certain condition
ind = np.where( a < 6 )
print( ind )
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),)
# print this specific data set
print( a[ ind ] )
[1. 1.5 2. 2.5 3. 3.5 4. 4.5 5. 5.5]
# find indices for multiple conditions
ind = np.where( (a < 6) & (a > 2) )
print( a[ ind ] )
[2.5 3. 3.5 4. 4.5 5. 5.5]
Shallow & Deep Copies / Views#
Warning
Be carefull with lists and arrays and their copies!
# define a simple list
a = [1, 2, 3]
# and a copy of it
b = a
print( "a:", a)
print( "b:", b)
a:
[1, 2, 3]
b: [1, 2, 3]
# now edit first element of a
a[0] = 100
print( "a:", a)
a: [100, 2, 3]
print( "b:", b)
b: [100, 2, 3]
a = np.arange(0,8)
print( a )
[0 1 2 3 4 5 6 7]
Warning
A simple assignment will not create a copy!
b = a
# reshape b
b.shape = (2, 4)
# print both
print( a )
print( b )
[[0 1 2 3]
[4 5 6 7]]
[[0 1 2 3]
[4 5 6 7]]
# check if a and b are the same objects
print( b is a )
True
a = np.arange(0, 8)
print( a )
[0 1 2 3 4 5 6 7]
# create a "view" / also called "shallow copy"
b = a.view()
# edit the view
b.shape = (2, 4)
# print both
print( a )
print( b )
[0 1 2 3 4 5 6 7]
[[0 1 2 3]
[4 5 6 7]]
# check if a and b are the same objects
print( b is a )
False
# edit an element of the shallow copy / view
b[0, 0] = -100
# print both
print( a )
print( b )
[-100 1 2 3 4 5 6 7]
[[-100 1 2 3]
[ 4 5 6 7]]
a = np.arange(0,8)
print( a )
[0 1 2 3 4 5 6 7]
# create a proper / deep copy
b = a.copy()
# edit the view
b.shape = (2, 4)
# print both
print( a )
print( b )
[0 1 2 3 4 5 6 7]
[[0 1 2 3]
[4 5 6 7]]
# check if a and b are the same objects
print( b is a )
False
# edit an element of the shallow copy / view
b[0,0] = -100
# print both
print( a )
print( b )
[0 1 2 3 4 5 6 7]
[[-100 1 2 3]
[ 4 5 6 7]]