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

时间:2018-01-25 11:54:27

标签: python netcdf python-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格式,而不是显示自...以来的过去...&#39;定义

谢谢!

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

你可以在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')

奖励答案,你可以用类似的方法选择时间片:

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中讨论过。