<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 NumPy Seralisation and I/O
In this notebook we will focus on NumPy built-in support for Serialisation and I/O. In other words, we will learn how to save and load NumPy ndarray objects in native (binary) format for easy sharing. Moreover we are going to discover how NumPy can load data from external files.
Step1:  Comma-separated values (CSV)
A very common file format for data files are the comma-separated values (CSV), or related format such as TSV (tab-separated values). 
To read data from such file into Numpy arrays we can use the numpy.genfromtxt function.
Step2:  DYI
Let's play a bit with the data loaded st_temperatures to combine fancy indexing (i.e. defining conditions to get subset of data) and very simple statistics.
For example
Step3:  Numpy's native file format
Useful when storing and reading back numpy array data. 
Use the functions np.save and np.load
Step4:  See also
Step5:  NumPy for Matlab Users (really?)
If you are a MATLAB&reg; user I do recommend to read Numpy for MATLAB Users.
Numpy can load and save native MATLAB® files
Step6:  If we try to add, subtract or multiply objects with incomplatible shapes we get an error
Step7:  See also the related functions
Step8:  Introducing SciPy (ecosystem)
scipy.io
Step9:  NumPy $\mapsto$ MATLAB 
Step10:  MATLAB $\mapsto$ NumPy
<ASSISTANT_TASK:>
Python Code:
import numpy as np
Explanation: NumPy Seralisation and I/O
In this notebook we will focus on NumPy built-in support for Serialisation and I/O. In other words, we will learn how to save and load NumPy ndarray objects in native (binary) format for easy sharing. Moreover we are going to discover how NumPy can load data from external files.
End of explanation
# In Jupyter, all commands starting with ! are mapped as SHELL commands
!head stockholm_td_adj.dat
np.genfromtxt?
st_temperatures = np.genfromtxt('stockholm_td_adj.dat', 
                                skip_header=1)
st_temperatures.shape
Explanation: Comma-separated values (CSV)
A very common file format for data files are the comma-separated values (CSV), or related format such as TSV (tab-separated values). 
To read data from such file into Numpy arrays we can use the numpy.genfromtxt function.
End of explanation
st_temperatures[:10, ]
st_temperatures.dtype
## Calculate which and how many years we have in our data
years = np.unique(st_temperatures[:, 0]).astype(np.int)
years, len(years)
years.min(), years.max()
!head stockholm_td_adj.dat
mask_year = st_temperatures[:, 0] == 1984
mask_feb = st_temperatures[:, 1] == 2
mask_feb.shape
mask_year.dtype
type(mask_year)
## Calculate the mean temperature of mid-days on February in 1984
feb_noon_temps = st_temperatures[(mask_year & mask_feb), 4]
type(feb_noon_temps)
feb_noon_temps.dtype
feb_noon_temps.mean()
## ....
Explanation: DYI
Let's play a bit with the data loaded st_temperatures to combine fancy indexing (i.e. defining conditions to get subset of data) and very simple statistics.
For example:
End of explanation
np.save("st_temperatures.npy", st_temperatures)
Explanation: Numpy's native file format
Useful when storing and reading back numpy array data. 
Use the functions np.save and np.load:
np.save
End of explanation
T = np.load("st_temperatures.npy")
print(T.shape, T.dtype)
Explanation: See also:
np.savez : save several NumPy arrays into one single file
np.savez_compressed
np.savetxt
np.load
End of explanation
from numpy import matrix
a = np.arange(0, 5)
A = np.array([[n+m*10 for n in range(5)] for m in range(5)])
a
A
M = matrix(A)
v = matrix(a).T # make it a column vector
a
M * M
A @ A  # @ operator equivalent to np.dot(A, A)
# Element wise multiplication in NumPy
A * A
M * v
A * a
# inner product
v.T * v
# with matrix objects, standard matrix algebra applies
v + M*v
Explanation: NumPy for Matlab Users (really?)
If you are a MATLAB&reg; user I do recommend to read Numpy for MATLAB Users.
Numpy can load and save native MATLAB® files:
The Matrix Array Type
In addition to the numpy.ndarray type, NumPy also support a very specific data type called Matrix. 
This special type of object has been introduced to allow for API and programming compatibility with
MATLAB®. 
Note: The most relevant feature of this new array type is the behavior of the standard arithmetic operators +, -, * to use matrix algebra, which work as they would in MATLAB.
End of explanation
v_incompat = matrix(list(range(1, 7))).T
M.shape, v_incompat.shape
M * v_incompat
Explanation: If we try to add, subtract or multiply objects with incomplatible shapes we get an error:
End of explanation
A = np.random.rand(10000, 300, 50)  # note: this may take a while
A
Explanation: See also the related functions: inner, outer, cross, kron, tensordot. 
Try for example help(inner).
Loading and Saving .mat file
Let's create a numpy.ndarray object
End of explanation
from scipy import io as spio
Explanation: Introducing SciPy (ecosystem)
scipy.io
End of explanation
spio.savemat('numpy_to.mat', {'A': A}, oned_as='row')  # savemat expects a dictionary
Explanation: NumPy $\mapsto$ MATLAB :  scipy.io.savemat
End of explanation
data_dictionary = spio.loadmat('numpy_to.mat')
list(data_dictionary.keys())
data_dictionary['A']
A_load = data_dictionary['A']
np.all(A == A_load)
type(A_load)
Explanation: MATLAB $\mapsto$ NumPy: scipy.io.loadmat
End of explanation
<END_TASK>