如何使从 netCDF (.nc) 加载的数组可写?

How to make an array loaded from netCDF (.nc) writeable?

我正在使用 python scipy.io.netcdf 模块从 netcdf (.nc) 文件加载一些变量。在我从中加载它们的文件中,缺失数据的填充值为 99999,我想将其从 numpy 更改为 np.nan

然而,一旦我导入了一个变量并将其分配给一个 numpy 数组,我就无法清除 99999 填充值,因为我得到:

    RuntimeError: array is not writeable

我试图将数组 writeable 的属性更改为 True 但是 returns:

    ValueError: cannot set WRITEABLE flag to True of this array

所以我很茫然。下面是我的代码的简化版本和几个示例输出。有人在这里有什么建议吗?最初我使用 netCDF4 而不是 scipy.io.netcdf,在那种情况下我会设置 nc.set_auto_mask(False) 但是我没有在 scipy.io 中看到类似的 属性 所以我有只是离开了。

示例代码:

    import scipy.io as sio
    import numpy as np

    nc = sio.netcdf.netcdf_file('filename.nc','r') # open file
    arr = nc.variables['PARAMETER'][:] # load into np array
    output_arr = cleanarr(arr) # replace filler 99999 vals with np.nan
    nc.close()

值得注意的是,我在 cleanarr(arr)

之前或之后执行 nc.close() 似乎并不重要

示例输出:

    type(arr)
        <type 'numpy.ndarray'>

    arr.flags
          C_CONTIGUOUS : True
          F_CONTIGUOUS : False
          OWNDATA : False
          WRITEABLE : False
          ALIGNED : True
          UPDATEIFCOPY : False

通过使用 np.require (http://docs.scipy.org/doc/numpy/reference/generated/numpy.require.html) 来更改标志而不是我使用的原始方法来解决。代码现在看起来像:

    import scipy.io as sio
    import numpy as np

    nc = sio.netcdf.netcdf_file('filename.nc','r') # open file
    arr = nc.variables['PARAMETER'][:] # load into np array
    arr = np.require(arr,dtype='f4',requirements=['O','W'])
    output_arr = cleanarr(arr) # replace filler 99999 vals with np.nan
    nc.close()

这似乎可以完成这项工作,但如果有人可以就是否应该或不应该这样做来评论我的回答的有效性(我觉得我在这里强迫某些事情,而且我从未使用过np.require 之前)我将不胜感激。

来自文档

http://docs.scipy.org/doc/scipy-0.15.1/reference/generated/scipy.io.netcdf.netcdf_file.html

NetCDF files, when opened read-only, return arrays that refer directly to memory-mapped data on disk:

>>>
>>> data = time[:]
>>> data.base.base
<mmap.mmap object at 0x7fe753763180>
If the data is to be processed after the file is closed, it needs to be copied to main memory:

>>>
>>> data = time[:].copy()
>>> f.close()
>>> data.mean()

我认为这在之前的 SO 问题中也得到了解决,尽管我没有花时间查看这些问题。