mirror of
https://github.com/janishutz/eth-summaries.git
synced 2026-01-13 21:08:28 +00:00
104 lines
6.0 KiB
TeX
104 lines
6.0 KiB
TeX
\newpage
|
|
\subsection{Numpy}
|
|
Numpy is a library that, according to its website, is ``The fundamental package for scientific computing with Python''.
|
|
|
|
If you prefer to read an online guide, the \hlhref{https://numpy.org/doc/stable/user/quickstart.html}{official quick start guide}\ is excellent.
|
|
|
|
\subsubsection{Arrays}
|
|
The heart of numpy is the \texttt{numpy.ndarray} class (it has the alias \texttt{numpy.array}). As the name would imply, it can be any dimension you would like.
|
|
The most important attributes for this course are: \texttt{shape} (returns a tuple that indicates the number of elements for each dimension),
|
|
\texttt{dtype} (indicates the data type of elements in the array),
|
|
\texttt{ndim} (the number of dimensions, equal to \texttt{len(shape)})
|
|
|
|
To create an array, we can use a few functions:
|
|
\drmvspace
|
|
\begin{multicols}{2}
|
|
\begin{itemize}[noitemsep]
|
|
\item \texttt{np.array([...])}
|
|
\item \texttt{np.zeros(shape)}
|
|
\item \texttt{np.zeros\_like(arr)}
|
|
\item \texttt{np.ones(shape)}
|
|
\item \texttt{np.ones\_like(arr)}
|
|
\item \texttt{np.empty\_like(arr)}
|
|
\item \texttt{np.arange(start, stop, step)}
|
|
\item \texttt{np.linspace(start, stop, num\_el)}
|
|
\item \texttt{np.logspace(start, stop, num\_el)}
|
|
\item \texttt{np.eye(N, M)} (\texttt{N} is rows, \texttt{M} is cols)
|
|
\item \texttt{np.identity(N, M)}
|
|
\item \texttt{np.fromfunction(f, (dim1, \dots))}
|
|
\end{itemize}
|
|
\end{multicols}
|
|
|
|
\dnrmvspace
|
|
To use complex numbers, we can write \texttt{a + b * 1.j}
|
|
|
|
Another useful method is \texttt{np.meshgrid(x, y, \dots)}, which returns a coordinate grid
|
|
and treats the input vectors as \texttt{x}, \texttt{y}, etc coordinates of point \texttt{i}.
|
|
|
|
Arrays aren't usually copied, but you get a view. The \texttt{reshape} method below is an example of a case where you get a shallow copy (that still technically is a view).
|
|
The values are still in the same object, but you get access to it in a different shape.
|
|
To deep copy an array (i.e. create a new array), use \texttt{arr.copy()}
|
|
|
|
|
|
\subsubsection{Operations}
|
|
The same basic operations that Python supports are also supported by numpy, though they are executed on each element.
|
|
|
|
\begin{itemize}[noitemsep]
|
|
\item You can subtract a number from an ndarray
|
|
\item You can subtract an ndarray from another ndarray (vector, matrix, ... difference)
|
|
\item To compute a matrix product (or matrix-vector product), you can do \texttt{A @ B} or \texttt{np.dot(A, B)}
|
|
\item \texttt{arr.sum()} sums up all elements and \texttt{arr.sum(axis=n)} sums up all elements on that axis (0 is column, 1 is row)
|
|
\item \texttt{arr.cumsum()} computes the cumulative sum (i.e. each element in the output is the sum of all preceding elements). You can also use the axis argument again.
|
|
\item \texttt{np.exp}, \texttt{np.sqrt}, etc operate element-wise on the array
|
|
\item \texttt{np.where(condition, arr\_true, arr\_false)} returns a numpy array where if \texttt{condition} is true,
|
|
element \texttt{i} is chosen from \texttt{arr\_true}, else from \texttt{arr\_false}
|
|
\end{itemize}
|
|
A useful trick to create a mask is to use \texttt{a < b} (or any other comparison), as that will return an array of booleans.
|
|
|
|
For piecewise interpolation, a useful method is \texttt{np.searchsorted(arr.flat, vals\_insert, side='right')}, where \texttt{vals\_insert} are the values to be inserted
|
|
and the \texttt{side} argument indicates on which side of the match they are to be inserted.
|
|
|
|
For that though, the array needs to be sorted, for which we can use \texttt{np.argsort(arr, axis=-1)}.
|
|
This will return the indices in the order that would sort the array along the given axis. If axis is unspecified, \texttt{-1} is used.
|
|
To use these indices to sort an array, we can simply use \texttt{arr[np.argsort(arr)]}.
|
|
|
|
|
|
Slicing and indexing works just as in Python (assume \texttt{a} is a numpy array):
|
|
\begin{code}{python}
|
|
a = np.arange(10)
|
|
print(a[2]) # Outputs 2 (third element)
|
|
print(a[-1]) # Outputs 9 (last element)
|
|
print(a[-2]) # Outputs 8 (2nd to last element)
|
|
print(a[2:5]) # Outputs [2, 3, 4] (elements 2, 3, and 4)
|
|
print(a[2:5:-1]) # Outputs [4, 3, 2] (reversed)
|
|
print(a[::-1]) # Reverses the array
|
|
\end{code}
|
|
So, the basic syntax for slicing is \texttt{a[start : stop : step]} and any of them can be omitted, though the corresponding colons cannot be omitted if you omit start.
|
|
|
|
We can also iterate over a numpy array normally (the iterator variable will be the \texttt{i}-th element of the outermost array of the numpy array).
|
|
To iterate over all elements of the array (i.e. the actual data values), we can use \texttt{arr.flat} to get a view (similar to a reference, not copied) that has
|
|
length that corresponds to the sum of all elements of \texttt{arr.shape}.
|
|
|
|
For \texttt{n}-d arrays, we can use \texttt{a[0, 1]} to access element \texttt{a[0][1]}, which is more efficient.
|
|
|
|
|
|
\subsubsection{Shape manipulation}
|
|
We can reshape an array by using \texttt{arr.reshape(dim1, dim2, \dots)}. This however returns the array with modified shape,
|
|
whereas \texttt{arr.resize((dim1, dim2, \dots))} modifies the array directly (notice that here we have to pass a tuple!)
|
|
|
|
To get a one-dimensional array, we can use \texttt{arr.ravel()}, after which the array looks the same
|
|
as \texttt{arr.flat}, but the change is permanent
|
|
|
|
|
|
\fhlc{Cyan}{Stacking arrays}
|
|
|
|
\texttt{np.vstack((a, b))} adds array \texttt{b}'s elements to array \texttt{a} (i.e. stacks along \texttt{axis=0}).
|
|
\texttt{np.hstack((a, b))} adds array \texttt{b}'s elements to the inner arrays of \texttt{a} (i.e. stacks along \texttt{axis=1}).
|
|
\texttt{np.concatenate((a, b, \dots), axis=n)} does as the above, but applies it to axis \texttt{n}
|
|
|
|
\fhlc{Cyan}{Splitting arrays}
|
|
|
|
\texttt{np.hsplit(a, count)} splits \texttt{a} into \texttt{count} arrays (along \texttt{axis=0})
|
|
\texttt{np.vsplit(a, count)} splits \texttt{a} into \texttt{count} arrays (along \texttt{axis=1})
|
|
\texttt{np.array\_split(a, count, axis=n)} splits \texttt{a} into \texttt{count} arrays (along \texttt{axis=n})
|