# Getting Things Done in Python¶

This notebook contains tips and tricks of working with vectors and matrices:

• How to generate arrays of numbers
• How to generate, matrices, row- and column-vectors
• How to reotate vectors
• And a first introduction into the often very valuable concept of "broadcasting"

author: Thomas Haslwanter, date: Feb-2017

## Generating Data¶

### Generating Evenly Spaced Vectors¶

In :
# import standard packages
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.mlab import frange

# To make the display prettier
%precision 3

Out:
'%.3f'
In :
# Note that with "arange" the last value is NOT included!
x = np.arange(1,5,0.5)
x

Out:
array([ 1. ,  1.5,  2. ,  2.5,  3. ,  3.5,  4. ,  4.5])
In :
# "linspace" produces a given number of linearly spaced numbers
y = np.linspace(0,1,11)
y

Out:
array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ])
In :
# "frange" includes the last value
z = frange(1,3)
z

Out:
array([ 1.,  2.,  3.])

### Generating Matrices¶

In :
# Unlike MATLAB, Python by default generates vectors, NOT matrices!
zero_vector = np.zeros(3)
zero_vector

Out:
array([ 0.,  0.,  0.])
In :
# "np.zeros" and "np.ones" generate zeros and ones, respecitvely.
# They only take ONE input argument, which can be a number or a tuple:
zero_matrix = np.zeros( (3,3))
zero_matrix

Out:
array([[ 0.,  0.,  0.],
[ 0.,  0.,  0.],
[ 0.,  0.,  0.]])
In :
# Note: "np.random.randn" in contrast can use more than one input argument:
np.random.randn(3,2)

Out:
array([[-1.036, -0.162],
[-0.292, -1.07 ],
[ 1.325,  1.29 ]])
In :
# Here an example of how to conveniently generate a matrix of column vectors:

sines = np.sin(phi)
cosines = np.cos(phi)

data_mat = np.column_stack((sines, cosines))

print(np.round(data_mat, 2))

[[ 0.    1.  ]
[ 0.5   0.87]
[ 0.87  0.5 ]
[ 1.    0.  ]
[ 0.87 -0.5 ]
[ 0.5  -0.87]
[ 0.   -1.  ]
[-0.5  -0.87]
[-0.87 -0.5 ]
[-1.   -0.  ]
[-0.87  0.5 ]
[-0.5   0.87]]


### Generate Row- and Column-vectors¶

In :
# A row-vector can be generated like this ...
row_vector = np.array([1,2,3])
row_vector

Out:
array([1, 2, 3])
In :
# ... or equivalently like that
row_vector2 = np.r_[3,4,5]
row_vector2

Out:
array([3, 4, 5], dtype=int32)
In :
# I know the syntax for generating column-vectors are all a bit weird :(
col_vector = np.c_[[4,5,6]]
col_vector

Out:
array([,
,
])
In :
# This one uses the command "np.newaxis" to generate a column vector ....
row_vector[..., np.newaxis]

Out:
array([,
,
])
In :
# ... and here is how to use the "reshape" command: the "-1" means "however many there are":
np.reshape(row_vector, (-1,1))

Out:
array([,
,
])

## Working with Vectors and Matrices¶

### Rotation of a vector¶

In :
# Rotation matrix for a rotation by 30 deg
rot_mat = np.array([[np.cos(alpha), -np.sin(alpha)],
[np.sin(alpha), np.cos(alpha)]])

# Note that there are two ways to specify a matrix multiplication
vec = np.r_[1,0]
vec_rotated = rot_mat.dot(vec)
vec_rotated_2 = rot_mat @ vec # for Python >3.5

# Show the results
print(rot_mat)
print('I rotated {0} into {1}'.format(str(vec), str(vec_rotated)))
np.all(vec_rotated == vec_rotated_2)

[[ 0.866 -0.5  ]
[ 0.5    0.866]]
I rotated [1 0] into [ 0.866  0.5  ]

Out:
True

In numpy, "broadcasting" is a convenient way of adding numbers or vectors to a matrix, is the dimensions match up.

Here, I show how to subtract the mean value from each column:

In :
# Generate some data
data = np.arange(15).reshape((5,3))
data

Out:
array([[ 0,  1,  2],
[ 3,  4,  5],
[ 6,  7,  8],
[ 9, 10, 11],
[12, 13, 14]])
In :
# overall mean
np.mean(data)

Out:
7.000
In :
# mean over all rows
np.mean(data, axis=0)

Out:
array([ 6.,  7.,  8.])
In :
# Now we use "broadcasting" to subtract the mean of each column:
# if the second index matches, the operation is applied to each row:
data - np.mean(data, axis=0)

Out:
array([[-6., -6., -6.],
[-3., -3., -3.],
[ 0.,  0.,  0.],
[ 3.,  3.,  3.],
[ 6.,  6.,  6.]])
In :
# This only works on the last index!
data - np.mean(data, axis=1)

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-19-cf2430189ce1> in <module>()
1 # This only works on the last index!
----> 2 data - np.mean(data, axis=1)

ValueError: operands could not be broadcast together with shapes (5,3) (5,)