Lucas Schmitz
Lucas Schmitz

Reputation: 3

TypeError when creating netcdf file

I am trying to creat a netcdf file. In the first step all I want is to read the data from a netcdf file and write it in a new netcfd file I have a data-array, that has the dtype float64 and three dimensions (time, latitude, longitude).

When I run the script I get the following error:

TypeError: ufunc 'subtract' did not contain a loop with signature matching types dtype('U32') dtype('U32') dtype('U32')

I understand, that somehow the datatypes don't match. But I don't see where the problem is.

fid = Dataset(Dir, "r")
t2m = np.array(fid.variables["t2m"])

#create new netcdf file
new_file = "ERA_t2m_2011to2017"
dataset = Dataset(new_file, "w", format="NETCDF3_64BIT_OFFSET")

#create dimensions
longitude = dataset.createDimension("longitude", 1200)
latitude = dataset.createDimension("latitude", 101)
time = dataset.createDimension("time", None)

#create variables
newvar = dataset.createVariable("longitude", np.float32, ("longitude"))
newvar.long_name = "longitude"
newvar.units = "degrees_east"
newvar.axis = "longitude-axis"
newvar[:] = np.array(fid.variables["longitude"])

newvar = dataset.createVariable("latitude", np.float32, ("latitude"))
newvar.long_name = "latitude"
newvar.units = "degrees_north"
newvar.axis = "latitude-axis"
newvar[:] = np.array(fid.variables["latitude"])

newvar = dataset.createVariable("time", np.int32, ("time"))
newvar.long_name = "time"
newvar.units = "hours since 1900-01-01 00:00:0.0"
newvar.calendar = "gregorian"
newvar.axis = "time-axis"
newvar[:] = np.array(fid.variables["time"])

newvar = dataset.createVariable("t2m", np.float64, ("time", "latitude", "longitude"))
newvar.long_name = "2 meter temperature"
newvar.units = "K"
newvar.FillValue = "-32767"
newvar.scale_factor = "0.00137038771743"
newvar.add_offset = "238.393472216"
newvar.missing_value = "-32767"
newvar[:] = t2m

Maybe an important information is also, that

fid.variables["t2m"]

yields the following output:

class 'netCDF4._netCDF4.Variable'

int16 t2m(time, latitude, longitude)

scale_factor: 0.00135205961432

add_offset: 238.864955074

_FillValue: -32767

missing_value: -32767

units: K

long_name: 2 metre temperature

unlimited dimensions: time current shape = (2920, 101, 1200) filling off

So the 2tm variable seems to be the dtype int32 at first, but it turns to be float64 when I read it in. However both creating the variable 2tm as float64 or as int32 leads to the same error.

Can you help me out here? Thank you.

Upvotes: 0

Views: 388

Answers (1)

Bart
Bart

Reputation: 10288

The problem is in how you specify:

newvar.FillValue = "-32767"
newvar.scale_factor = "0.00137038771743"
newvar.add_offset = "238.393472216"
newvar.missing_value = "-32767"

scale_factor and add_offset should be numerical values, not strings. FillValue and missing_value can be strings (at least, in my small test), but you probably want to make them numerical as well.

From the documentation:

When data is written to a variable it is packed using::

data = (data - self.add_offset)/self.scale_factor

This is where the error comes from, for example:

np.array(1.)-'string'

Results in the exact same error as you get.

Upvotes: 1

Related Questions