【问题标题】:Regrid Netcdf file in pythonPython中的Regrid Netcdf文件
【发布时间】:2020-08-31 12:25:57
【问题描述】:

我正在尝试将 NetCDF 文件从 0.125 度重新网格化到 0.083 度空间比例。 netcdf 包含 224 个纬度和 464 个经度,并且有一年的每日数据。

我为它尝试了 xarray,但它产生了这个内存错误: MemoryError: Unable to allocate 103. GiB for an array with shape (13858233841,) and data type float64

如何使用 python 重新网格化文件?

【问题讨论】:

标签: python interpolation netcdf python-xarray netcdf4


【解决方案1】:

Xarray 使用称为“延迟加载”的东西来尝试避免使用过多的内存。在您的代码中的某处,您正在使用一个将全部数据加载到内存中的命令,这是它无法做到的。相反,您应该指定计算,然后将结果直接保存到文件中。 Xarray 将一次执行一个块的计算,而不会将所有内容加载到内存中。

重新网格化的示例可能如下所示:

da_input = open_dataarray(
    'input.nc') # the file the data will be loaded from
regrid_axis = np.arange(-90, 90, 0.125) # new coordinates
da_output = da_input.interp(lat=regrid_axis) # specify calculation
da_ouput.to_netcdf('output.nc') # save direct to file

例如,执行da_input.load()da_output.compute() 会导致所有数据都加载到内存中——这是您想要避免的。

【讨论】:

    【解决方案2】:

    最简单的方法是使用 CDO、NCO 和 NCL 等运算符。

    例如。

    cdo remapbil,target_grid infile.nc ofile.nc
    

    target_gid 可以是描述符文件,或者您可以使用具有所需网格分辨率的 NetCDF 文件。请注意其他可能适合您需要的重新网格化方法。上面的例子是使用双线性插值。

    【讨论】:

      【解决方案3】:

      另一个选项是尝试cf-python,它可以(通常)在球极坐标和笛卡尔坐标中重新网格大于内存的数据集。它使用 ESMF 重新网格化引擎来完成此操作,因此可以使用线性、一阶和二阶保守、最近邻等重新网格化方法。

      以下是您需要的重新网格化示例:

      import cf
      import numpy
      
      f = cf.example_field(2) # Use cf.read to read your own data
      
      print('Source field:')
      print(f)
      
      # Define the output grid
      lat = cf.DimensionCoordinate(
                 data=cf.Data(numpy.arange(-90, 90.01, 0.083), 'degreesN'))
      lon = cf.DimensionCoordinate(
                data=cf.Data(numpy.arange(0, 360, 0.083), 'degreesE'))
      
      # Regrid the field
      g = f.regrids({'latitude': lat, 'longitude': lon}, method='linear')
      
      print('\nRegridded field:')
      print(g)
      

      产生:

      Source field:
      Field: air_potential_temperature (ncvar%air_potential_temperature)
      ------------------------------------------------------------------
      Data            : air_potential_temperature(time(36), latitude(5), longitude(8)) K
      Cell methods    : area: mean
      Dimension coords: time(36) = [1959-12-16 12:00:00, ..., 1962-11-16 00:00:00]
                      : latitude(5) = [-75.0, ..., 75.0] degrees_north
                      : longitude(8) = [22.5, ..., 337.5] degrees_east
                      : air_pressure(1) = [850.0] hPa
      
      Regridded field:
      Field: air_potential_temperature (ncvar%air_potential_temperature)
      ------------------------------------------------------------------
      Data            : air_potential_temperature(time(36), latitude(2169), longitude(4338)) K
      Cell methods    : area: mean
      Dimension coords: time(36) = [1959-12-16 12:00:00, ..., 1962-11-16 00:00:00]
                      : latitude(2169) = [-90.0, ..., 89.94399999999655] degreesN
                      : longitude(4338) = [0.0, ..., 359.971] degreesE
                      : air_pressure(1) = [850.0] hPa
      
      

      有很多选项可以从其他字段获取目标网格,以及明确定义它。更多详情可查看in the documentation

      cf-python 将从附加到数据集的 CF 元数据中推断出哪些轴是 X 和 Y 等,但如果缺少这些,那么总有办法手动设置或解决它。

      【讨论】:

        【解决方案4】:

        使用 CDO 作为后端的 Python 选项是我的包 nctoolkit:https://nctoolkit.readthedocs.io/en/latest/,可通过 pip (https://pypi.org/project/nctoolkit/) 安装

        它有一个名为 to_latlon 的内置方法,它将重新网格到指定的纬度网格

        在你的情况下,你需要这样做:

        将 nctoolkit 导入为 nc

        数据 = nc.open_data(infile)

        data.to_latlon(lon = [lon_min, lon_max], lat = [lat_min, lat_max], res = [0.083, 0.083])

        【讨论】:

          【解决方案5】:

          从 python 中访问 c​​do 功能的另一种方法是使用Pypi cdo project

          pip install cdo 
          

          那你就可以了

          from cdo import Cdo
          cdo=Cdo()
          cdo.remapbil("target_grid",input="in.nc",output="out.nc")
          

          target_grid 是你常用的选项列表

          1. 使用网格的 nc 文件
          2. 常规网格说明符,例如r360x180
          3. 带有网格描述符的 txt 文件(见下文)

          有几种内置的重新网格化方法:

          • remapbic:双三次插值
          • remapbil:双线性插值
          • remapnn:最近邻插值
          • remapcon:一阶保守重映射
          • remapcon2:二阶保守重映射

          您可以使用网格描述符文件来定义需要插值的区域...

          在文件grid.txt中

          gridtype=lonlat
          xfirst=X   (here X is the longitude of the left hand point)
          xinc=0.083
          xsize=NX   (here put the number of points in domain)
          yfirst=Y
          yinc=0.083
          ysize=NY
          

          更多详情可以参考我的video guide on interpolation

          【讨论】:

            猜你喜欢
            • 2014-10-20
            • 1970-01-01
            • 1970-01-01
            • 2016-11-08
            • 2012-12-05
            • 1970-01-01
            • 2013-12-18
            • 2017-02-08
            • 2015-11-17
            相关资源
            最近更新 更多