Home

Numpy

Numpy is an abbreviation of NUMerical Python. It adds support for multi-dimensional arrays and matrices, as well as many of the algebraic formulae often used in working with these structures.

For a great tutorial see: https://docs.scipy.org/doc/numpy/user/quickstart.html

Recall that the main Python datastructs are as follows:

xs = [1,'1',2,'2']                    # list := mutable & unordered collection of items
xd = {'cat': 'cute', 'dog': 'furry'}  # dictionary:= (key,value) pairs
xa = {'cat', 'dog'}                   # set := unordered collection of distinct elements
xt = (5, 6)                           # tuple := immutable & ordered list of values

NDArray

A numpy array is a grid of values, all of the same type, and is indexed by a tuple of nonnegative integers.
rank = number of dimensions of the array
shape= a tuple of integers giving the size of the array along each dimension

Creation

b = np.array([[1,2,3],[4,5,6]])       # Create a rank 2 array from 2 python lists
print(b.shape)                        # Prints "(2, 3)"
print(b[0, 0], b[0, 1], b[1, 0])      # Prints "1 2 4"

np.arange( 10, 30, 5 )                # creates a sequence of numbers similar to range
#>>> array([10, 15, 20, 25])          
    # arange() can also work with floating numbers but this is inadvisable as it the number of elements is unpredictable
    # Use linspace instead when dealing with floats

np.linspace( 0, 2, 9 )                # 9 numbers from 0 to 2
#>>> array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ,  1.25,  1.5 ,  1.75,  2.  ])

# there are some built in functions to create and populate often used arrays
np.zeroes((2,2))         # 2x2 array of zeroes
np.empty((2,2))          # 2x2 uninitialized, output may vary 
np.ones((2,2))           # 2x2 array of ones
np.full((2,2), 7)        # 2x2 array of sevens
np.eye(2)                # 2x2 identity matrix
np.random.random((2,2))  # 2x2 array of random numbers between(0,1)

Basic Ops

Arithmetic operators on arrays apply elementwise. A new array is created and filled with the result.

a = np.array( [20, 30, 40, 50] )
b = np.arange( 4 )
c = a-b                           # c(0,0) = [a(0,0)-b(0,0), ...etc ]
b**2                              # each element of b raised to the 2nd power
10*np.sin(a)                      # [10*sine(a(0,0)), ... ,10*sine(a(3,3))
a < 35                            # array([ True, True, False, False])

A = np.array( [[1,1],[0,1]] )
B = np.array( [[2,0],[3,4]] )
A * B                             # elementwise product
A @ B                             # matrix product
A.dot(B)                          # another matrix product

# Some operations, such as += and *=, act in place to modify an existing array rather than create a new one.
a = np.ones((2,3), dtype=int)
b = np.random.random((2,3))
a *= 3                            # multiply each element of a by 3
b += a                            # upcasting is permitted
                                  # adds each element of a to the corresponding element of b
#  a += b                         # Downcasting is not permitted
                                  # ERROR: b is not automatically converted to integer type

Math Functions

b = np.arange(10)**3     # create an array
#>>> [  0   1   8  27  64 125 216 343 512 729]

a = b.reshape(2,5)
#>>> [[  0   1   8  27  64]
#>>>  [125 216 343 512 729]]

a.sum()                  # sum all elements
a.sum(axis=0)            # sum each row
a.sum(axis=1)            # sum each column
    # Similarly there is min(), max(), cumsum() cumulative summation
    #

Indexing

a = np.arange(10)**3          # Create a 1dim array
#>>> array([  0,   1,   8,  27,  64, 125, 216, 343, 512, 729])
a[2]                          # get element at i = 2
a[2:5]                        # get elements [2,3,4] 
a[:6:2] = -1000               # from start to position 6, exclusive, set every 2nd element to -1000
                              # equivalent to a[0:6:2] = -1000
a[ : :-1]                     # a in reverse order 

for i in a:                   # iterate over a
    print(i**(1/3.))
In [24]:
a = np.arange(10)**3          # Create a 1dim array
#>>> array([  0,   1,   8,  27,  64, 125, 216, 343, 512, 729])
a[2:5] 
Out[24]:
array([ 8, 27, 64], dtype=int32)