问题描述
运行下面的测试代码,给我一些奇怪的结果:
import numpy as np
from netCDF4 import Dataset
array1 = np.array([[1,2,3]])
array2 = np.array([[4,5,6],[7,8,9]])
rootgrp = Dataset("D:/test.nc","w",format="NETCDF4")
rootgrp.createDimension("0",None)
rootgrp.createDimension("1",None)
variable1 = rootgrp.createVariable("variable1",array1.dtype.str,("0","1"),fill_value=-1)
variable2 = rootgrp.createVariable("variable2",array2.dtype.str,fill_value=-1)
variable1[:] = array1
variable2[:] = array2
result1 = rootgrp['variable1'][:]
result2 = rootgrp['variable2'][:]
result1 返回:
masked_array(
data=[[1,3],[--,0]],mask=[[False,False,False],[ True,False]],fill_value=-1)
但我希望 -1 的填充值包含在第二行的所有值中,以及掩码中,第二行中的所有 True 值,因为没有数据,如下所示:
masked_array(
data=[[1,[-1,-1,-1]],True,True]],fill_value=-1)
并且 result2 返回:
masked_array(
data=[[4,9]],mask=False,fill_value=999999)
但期望填充值也为 -1,如下所示:
masked_array(
data=[[4,fill_value=-1)
我做错了什么?
解决方法
我认为这种行为源于对 netCFD 文件存储其数据的方式的误解。从我可以从您的代码中推测,您正在尝试创建一个包含二维数据的文件,然后添加要存储的数据。
netCFD 文件除了保存值外,还保存每个维度的值范围。正如名称维度所暗示的那样,这些值必须保存为一维变量。这告诉文件数据有多大。 tutorial
中描述了需要将维度保存为变量确实可以使用无限变量,就像您在 None
行中使用 rootgrp.createDimension("0",None)
所做的那样,但那些通常仍然具有一维变量,因为您知道它们是维度。
在这种情况下,您可以使用以下代码实现所需的结果:
import numpy as np
from netCDF4 import Dataset
# define the variables ranges
variable_array1 = np.array([1,2])
variable_array2 = np.array([1,2,3])
# define the data to be stored
data_array1 = np.array([[1,3]])
data_array2 = np.array([[4,5,6],[7,8,9]])
rootgrp = Dataset("D:/test.nc","w",format="NETCDF4")
rootgrp.createDimension("0",2)
rootgrp.createDimension("1",3)
# register the variables
variable1 = rootgrp.createVariable("variable1",variable_array1.dtype,("0",),fill_value=-1)
variable2 = rootgrp.createVariable("variable2",variable_array2.dtype,("1",fill_value=-1)
# register the data
data1 = rootgrp.createVariable("data1",data_array1.dtype,"1"),fill_value=-1)
data2 = rootgrp.createVariable("data2",data_array2.dtype,fill_value=-1)
# add the variable values
variable1[:] = variable_array1
variable2[:] = variable_array2
# add the data
data1[0,:] = data_array1
data2[:,:] = data_array2
result1 = rootgrp['data1'][:]
result2 = rootgrp['data2'][:]
如果您确实需要维度变量不受限制,您仍然需要首先添加您当前拥有的维度值。
直接添加数据会导致您面临的错误。为了解决这个问题,我们可以用 NumPy 附加数据,然后将其传递给文件。
在这种情况下,以下代码可能会有所帮助:
import numpy as np
from netCDF4 import Dataset
# define the variables ranges
variable_array1 = np.array([1,None)
rootgrp.createDimension("1",None)
# register the variables
variable1 = rootgrp.createVariable("variable1",fill_value=-1)
# add the variable values
variable1[:] = variable_array1
variable2[:] = variable_array2
# convert the data to python
data = data1[:]
# append the data
data[0,:] = data_array1
data1[:] = data
# convert the data to python
data = data2[:]
# append the data
data[:] = data_array2
data2[:,:] = data
result1 = rootgrp['data1'][:]
result2 = rootgrp['data2'][:]
如果您不同意我的观点,即该文件需要具有维度的一维变量才能工作,您可能已经找到了库的边缘情况,您可能认为它是库中的一个错误,并且您可能希望在 project's GitHub 中提交票证。
这是我的解决方法:
import numpy as np
from netCDF4 import Dataset
array1 = np.array([[1,3]])
array2 = np.array([[4,array1.dtype,array2.dtype,fill_value=-1)
# add the variable values
variable2[:] = array2
variable = np.full_like(variable2[:],-1)
variable[:] = array2
variable2[:] = variable
# add the variable values
variable1[:] = array1
variable = np.full_like(variable1[:],-1)
variable[0,:] = array1
variable1[:] = variable
result1 = rootgrp['variable1'][:]
result2 = rootgrp['variable2'][:]
此外,如果您不需要尺寸不受限制:
import numpy as np
from netCDF4 import Dataset
array1 = np.array([[1,fill_value=-1)
# add the variable values
variable1[0,:] = array1
variable2[:] = array2
result1 = rootgrp['variable1'][:]
result2 = rootgrp['variable2'][:]