netCDF4 填充值行为

问题描述

运行下面的测试代码,给我一些奇怪的结果:

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'][:]

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...