Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
examples:
```
print('Gaussian (mean: 0, stddev: 1):')
print(npr.normal(0, 1, (3, 3)))
print('Gamma (shape: 1, scale: 1):')
print(npr.normal(1, 1, (3, 3)))
print('Chi-square (dof: 10):')
print(npr.chisquare(10, (3, 3)))
```
The `numpy.random` module also has a couple of other handy functions for
random sampling of existing data:
```
data = np.arange(5)
print('data: ', data)
print('two random values: ', npr.choice(data, 2))
print('random permutation: ', npr.permutation(data))
# The numpy.random.shuffle function
# will shuffle an array *in-place*.
npr.shuffle(data)
print('randomly shuffled: ', data)
```
<a class="anchor" id="appendix-importing-numpy"></a>
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
For interactive exploration/experimentation, you might want to import
Numpy like this:
```
from numpy import *
```
This makes your Python session very similar to Matlab - you can call all
of the Numpy functions directly:
```
e = array([1, 2, 3, 4, 5])
z = zeros((100, 100))
d = diag([2, 3, 4, 5])
print(e)
print(z)
print(d)
```
But if you are writing a script or application using Numpy, I implore you to
import Numpy (and its commonly used sub-modules) like this instead:
import numpy as np
import numpy.random as npr
import numpy.linalg as npla
```
The downside to this is that you will have to prefix all Numpy functions with
`np.`, like so:
```
e = np.array([1, 2, 3, 4, 5])
z = np.zeros((100, 100))
d = np.diag([2, 3, 4, 5])
print(e)
print(z)
print(d)
```
There is a big upside, however, in that other people who have to read/use your
code will like you a lot more. This is because it will be easier for them to
figure out what the hell your code is doing. Namespaces are your friend - use
them!
<a class="anchor" id="appendix-vectors-in-numpy"></a>
One aspect of Numpy which might trip you up, and which can be quite
frustrating at times, is that Numpy has no understanding of row or column
vectors. __An array with only one dimension is neither a row, nor a column
vector - it is just a 1D array__. If you have a 1D array, and you want to use
it as a row vector, you need to reshape it to a shape of `(1, N)`. Similarly,
to use a 1D array as a column vector, you must reshape it to have shape
`(N, 1)`.
In general, when you are mixing 1D arrays with 2- or N-dimensional arrays, you
need to make sure that your arrays have the correct shape. For example:
r = np.random.randint(1, 10, 3)
print('r is a row: ', r)
print('r.T should be a column: ', r.T, ' ... huh?')
print('Ok, make n a 2D array with one row: ', r.reshape(1, -1))
print('We could also use the np.atleast_2d function:', np.atleast_2d(r))
print('Now we can transpose r to get a column:')
print(np.atleast_2d(r).T)
<a class="anchor" id="appendix-the-numpy-matrix"></a>
## Appendix D: The Numpy `matrix`
By now you should be aware that a Numpy `array` does not behave in quite the
same way as a Matlab matrix. The primary difference between Numpy and Matlab
is that in Numpy, the `*` operator denotes element-wise multiplication,
whereas in Matlab, `*` denotes matrix multiplication.
Numpy does support the `@` operator for matrix multiplication, but if this is
a complete show-stopper for you - if you just can't bring yourself to write
`A @ B` to denote the matrix product of `A` and `B` - if you _must_ have your
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
code looking as Matlab-like as possible, then you should look into the Numpy
[`matrix`](https://docs.scipy.org/doc/numpy/reference/generated/numpy.matrix.html)
data type.
The `matrix` is an alternative to the `array` which essentially behaves more
like a Matlab matrix:
* `matrix` objects always have exactly two dimensions.
* `a * b` denotes matrix multiplication, rather than elementwise
multiplication.
* `matrix` objects have `.H` and `.I` attributes, which are convenient ways to
access the conjugate transpose and inverse of the matrix respectively.
Note however that use of the `matrix` type is _not_ widespread, and if you use
it you will risk confusing others who are familiar with the much more commonly
used `array`, and who need to work with your code. In fact, the official Numpy
documentation [recommends against using the `matrix`
type](https://docs.scipy.org/doc/numpy-dev/user/numpy-for-matlab-users.html#array-or-matrix-which-should-i-use).
But if you are writing some very maths-heavy code, and you want your code to
be as clear and concise, and maths/Matlab-like as possible, then the `matrix`
type is there for you. Just make sure you document your code well to make it
clear to others what is going on!
<a class="anchor" id="useful-references"></a>
## Useful references
* [The Numpy manual](https://docs.scipy.org/doc/numpy/)
* [Linear algebra in `numpy.linalg`](https://docs.scipy.org/doc/numpy/reference/routines.linalg.html)
* [Broadcasting in Numpy](https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
* [Indexing in Numpy](https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html)
* [Random sampling in `numpy.random`](https://docs.scipy.org/doc/numpy/reference/routines.random.html)
* [Python slicing](https://www.pythoncentral.io/how-to-slice-listsarrays-and-tuples-in-python/)
* [Numpy for Matlab users](https://docs.scipy.org/doc/numpy-dev/user/numpy-for-matlab-users.html)