Search code examples
pythonpython-2.7netcdfdimensionnetcdf4

python, netcdf4: need intorduction in creating a unlimited time dimension for netcdf


Can somebody give an introduction in how to create an unlimited time dimension for a NetCDF file? I tried to use data.createDimension('t', None), but when I look at t it is a Numpy array. If possible, please give an introduction in assigning values to it too. I am using python 2.7.

edited question

I have multiple NetCDF-files (3 dimensions) and for each I have to calculate an array (3 dimensions). The time step between the files is 3 hours. Now I have to create a new NetCDF with the calculated array for each time step. My Problem is, that I do not know how to access the time axis, so that I can assign the calculated array to the different time step it.

edited question

I want to assign a date to the time axis. For creating the date I have used datetime like this:

t_start = dt.datetime(1900,1,1)
t_delta = dt.timedelta(hours=3)

The time between two timesteps is 3 hours. While looping over the files the date for the time step is calculated like this:

t_mom = t_start + i*t_delta
t_mom_str = t_mom.strftime("%d %B %Y %H  %M  %S")
t_mom_var = netCDF4.stringtochar(np.array([t_mom_str]))

I have created a Variable like this:

time = data.createVariable('time', np.float32, ('time'))

Now I want to assign the date to the time variable:

time[i] = t_mom_var[:]

But it is not working this way. Thanks for helping.


Solution

  • Using createDimension with None should work:

    import netCDF4 as nc4
    import numpy as np
    
    f = nc4.Dataset('test.nc', 'w')
    
    # Create the unlimited time dimension:
    dim_t = f.createDimension('time', None)
    # Create a variable `time` using the unlimited dimension:
    var_t = f.createVariable('time', 'int', ('time'))
    # Add some values to the variable:
    var_t[:] = np.arange(10)
    f.close()
    

    This results in (ncdump -h test.nc):

    netcdf test {
    dimensions:
        time = UNLIMITED ; // (10 currently)
    variables:
        int64 time(time) ;
    }
    

    For the updated question, a minimal working example of how to merge multiple files into one by adding a new unlimited dimension:

    import netCDF4 as nc4
    import numpy as np
    
    # Lets quickly create 3 NetCDF files with 3 dimensions
    for i in range(3):
        f = nc4.Dataset('test_{0:1d}.nc'.format(i), 'w')
    
        # Create the 3 dimensions
        dim_x = f.createDimension('x', 2)
        dim_y = f.createDimension('y', 3)
        dim_z = f.createDimension('z', 4)
        var_t = f.createVariable('temperature', 'double', ('x','y','z'))
    
        # Add some dummy data
        var_t[:,:,:] = np.random.random(2*3*4).reshape(2,3,4)
    
        f.close()
    
    # Now the actual merging:
    # Get the dimensions (sizes) from the first file:
    f_in = nc4.Dataset('test_0.nc', 'r')
    dim_size_x = f_in.dimensions['x'].size
    dim_size_y = f_in.dimensions['y'].size
    dim_size_z = f_in.dimensions['z'].size
    dim_size_t = 3
    f_in.close()
    
    # Create new NetCDF file:
    f_out = nc4.Dataset('test_merged.nc', 'w')
    
    # Add the dimensions, including an unlimited time dimension:
    dim_x = f_out.createDimension('x', dim_size_x)
    dim_y = f_out.createDimension('y', dim_size_y)
    dim_z = f_out.createDimension('z', dim_size_z)
    dim_t = f_out.createDimension('time', None)
    
    # Create new variable with 4 dimensions
    var_t = f_out.createVariable('temperature', 'double', ('time','x','y','z'))
    
    # Add the data
    for i in range(3):
        f_in = nc4.Dataset('test_{0:1d}.nc'.format(i), 'r')
        var_t[i,:,:,:] = f_in.variables['temperature'][:,:,:]
        f_in.close()
    
    f_out.close()