How to convert .mat file into netcdf file (.nc) using Python?

Viewed 166

I have different .mat files such as file_1.mat, file_2.mat, ..., file_n.mat with var1, var2, ..., varn in each file_x.mat. The variables do have the same name between the different files but not the same shape. However, their shape is equal within the same .mat file.

I usually load them in Python with spicy.io.loadmat() (documentation here) but I want to convert them to netcdf to use them later with xarray and accelerate my computation time. I was thinking some of you must have done this before me, jumping from Matlab to Python.

Is there any built-in function to do that ? Since my variables have the same name, I think something can be created with not too much difficulties, except we need to access the different dimensions of my variables depending on the file.

Thanks !!

1 Answers

I have something and I think it is a first step from what I want to do. It is really specific to my request. The thing is, you need to understand what is in your matfile, before constructing the appropriate dimensions.

def convert_to_nc(num:int, step:str, nn:str):
# nn correspond to a path to access the .mat file and where I want to save my new netcdf file
if nn == 'CANYONB':
    chemin = 'xx/{}.mat'.format(num)
elif nn == 'ESPER':
    chemin = 'xy/{}.mat'.format(num)
elif nn == 'CONTENT':
    chemin = 'yy/{}.mat'.format(num)
matfile = sc.io.loadmat(chemin)   
# CONDITION to choose the variables we want from the .mat file
var = [i for i in matfile[step].dtype.names if 'ci' not in i]
#var = [i for i in var if 'sigma' not in i]
#var = [i for i in var if 'raw' not in i]
#var = [i for i in var if 'cy' not in i]
print(var)
# I will open another netcdf file to look for the corresponding dimensions
ds = xr.open_dataset('my_alreadygoodnetcdf_{}.nc'.format(num))
ds_exit = xr.Dataset()
for name in range(len(var)):
    ds_exit[var[name]] = (("PRES_INTERPOLATED", "N_PROF"), matfile[step][var[name]][0][0])
ds_exit = ds_exit.assign_coords(TIME=("N_PROF", ds['TIME'].values)).assign_coords(LATITUDE=("N_PROF", ds['LATITUDE'].values)).assign_coords(LONGITUDE=("N_PROF", ds['LONGITUDE'].values)).assign_coords(N_PROF=("N_PROF", ds['N_PROF'].values)).assign_coords(PRES_INTERPOLATED=("PRES_INTERPOLATED", ds['PRES_INTERPOLATED'].values))
if nn == 'CANYONB':
    save_path = 'xx/{}.nc'.format(num)
elif nn == 'ESPER':
    save_path = 'xy/{}.nc'.format(num)
elif nn =='CONTENT':
    save_path = 'yy/{}.nc'.format(num)

ds_exit.to_netcdf(save_path)
return ds_exit

RUN

convert_to_nc(1901212, 'out', 'CONTENT')
Related