代码之家  ›  专栏  ›  技术社区  ›  Light_B jezrael

类似于xarray的Netcdf时间切片方法

  •  0
  • Light_B jezrael  · 技术社区  · 8 年前

    我有一个包含海冰浓度的NetCDF数据文件

    from netCDF4 import Dataset
    ds = Dataset('file.nic', 'r')
    ds.variables.keys()
    >>odict_keys(['latitude', 'longitude', 'seaice_conc', 'seaice_source', 'time'])
    ds.dimensions.keys()
    >>odict_keys(['latitude', 'longitude', 'time'])
    

    问题 :在此数据集中,自2001-01-01 00:00:00起,时间存储为天。假设我想要seaice\u conc for a specific time=1990-12-01,那么如何在不使用xarray或编写另一个函数来计算日差的情况下实现它呢。 有没有可能像在沙雷那样做,例如;

    import xarray as xr
    ds1 = xr.open_dataset('file.nc')
    seaice_data = ds1['seaice_conc'].sel(time = '1990-12-01')
    

    为了提供有关数据集的进一步信息,它如下所示:

    ds1.seaice_conc
    <xarray.DataArray 'seaice_conc' (time: 1968, latitude: 240, longitude: 
    1440)>
    [680140800 values with dtype=float32]
    Coordinates:
    * latitude   (latitude) float32 89.875 89.625 89.375 89.125 88.875 88.625 
    ...
    * longitude  (longitude) float32 0.125 0.375 0.625 0.875 1.125 1.375 1.625 
    ...
    * time       (time) datetime64[ns] 1850-01-15 1850-02-15 1850-03-15 ...
    Attributes:
    short_name: concentration
    long_name: Sea_Ice_Concentration
    standard_name: Sea_Ice_Concentration
    units: Percent
    

    还有一件事 我感到困惑的是,使用netcdf时,时间是以天为单位存储的,从2001:01:01开始,但在xarrays中,它以yyyy-mm-dd格式显示确切的日期,而不是显示“从……开始的天”释义

    谢谢

    3 回复  |  直到 8 年前
        1
  •  1
  •   Light_B jezrael    8 年前

    我能找到的最简单的方法是

    from netCDF4 import date2index
    from datetime import datetime
    timeindex = date2index(datetime(1990,12,1),ds.variables['time'])
    seaice_data = ds.variables['seaice_conc'][timeindex,:,:]
    
        2
  •  0
  •   kakk11    8 年前

    Dataset确实是一种比xarray低级别的库,如果它可以做xarray已经做的一切,那么就不需要xarray了,对吧。 不过,还有一个有用的功能 num2date 在netCDF4中,这可以使您在管理日期单位时更加轻松。大约:

    from netCDF4 import Dataset, num2date
    import datetime
    import numpy as np
    
    ds = Dataset('file.nic', 'r')
    your_date = datetime.datetime(1990,12,1)
    select_time = np.argmax(num2date(ds.variables['time'][:],ds.variables['time'].units) == your_date)
    seaice_data = ds.variables['seaice_conc'][select_time,:,:]
    

    我承认它仍然比xarray更具代码性。

        3
  •  0
  •   jhamman    8 年前

    你可以在沙雷做你想做的事。

    对于问题1 . 看起来你的约会都在每月的15号。只选择一个时间点应该是这样的。

    ds1['seaice_conc'].sel(time='1990-12-15')
    

    另一种方法是使用 method='nearest' 关键字参数。

    ds1['seaice_conc'].sel(time='1990-12-01', method='nearest')
    

    最后,您可以考虑将时间轴重新索引到每个月的第一个月。

    ds1['seaice_conc'].resample(time='MS').mean('time').sel(time='1990-12-01')
    

    一个额外的答案是,您可以使用类似的方法选择时间片:

    ds1['seaice_conc'].sel(time=slice('1990-01-01', '1991-12-31')
    

    Xarray文档包括 section on datetime indexing

    对于问题2 . 使用时,Xarray会自动解码坐标变量 open_dataset . 您可以使用 decode_times 但这似乎不是你想在这里做的。

    Xarray中也讨论了这一点 documentation .