Netcdf中类似于xarray的时间分片方法

Method for Time Slicing in Netcdf similar to xarray

我有一个包含海冰浓度的 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_conc 特定时间 = 1990-12-01 那么我如何在不使用 xarray 或编写另一个函数来计算天差的情况下处理它。 是否可以像在 xarrays 中那样做,例如;

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 格式而不是显示 'days since...' 定义?

谢谢!

netCDF4.Dataset确实是一种比xarray更底层的库,如果它能做xarray已经做的所有事情,就不需要xarray了,对吧。 不过,netCDF4 中有一个有用的函数 num2date,它可以让您在管理日期单位时更轻松。大约:

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代码多。

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

from netCDF4 import date2index
from datetime import datetime
timeindex = date2index(datetime(1990,12,1),ds.variables['time'])
seaice_data = ds.variables['seaice_conc'][timeindex,:,:]

您可以在 Xarray 中做您想做的事。

对于问题 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')

一个额外的答案,你可以用类似的方法 select 时间片:

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

Xarray 文档包含 section on datetime indexing

对于问题 2。当您使用 open_dataset 时,Xarray 会自动解码坐标变量。您可以使用 decode_times 参数将其关闭,但这似乎不是您想在此处执行的操作。

Xarray documentation 中也对此进行了讨论。