在xarray中删除重复时间

10
我正在使用open_mfdataset读取包含重复时间的NetCDF文件。对于每个重复的时间,我只想保留第一次出现,并删除第二次出现(它永远不会再次出现)。这个问题与这个Pandas问题非常相似,但是那里提供的解决方案似乎都无法在Xarray中工作。
要复制此问题:
import numpy as np
import netCDF4 as nc4
import xarray as xr

# Create example NetCDF files
for t in range(2):
    nc    = nc4.Dataset('test{}.nc'.format(t), 'w')
    dim_t = nc.createDimension('time', None)
    var_t = nc.createVariable('time', 'f8', ('time',))
    var_s = nc.createVariable('var', 'f8', ('time',))
    var_t.setncattr('units', 'hours since 2001-01-01 00:00:00')
    var_t[:] = t*5+np.arange(6)
    var_s[:] = t*5+np.arange(6)+t
    nc.close()

# Read with xarray
f = xr.open_mfdataset(['test0.nc', 'test1.nc'])

生成的数据集中的时间为:
array(['2001-01-01T00:00:00.000000000', '2001-01-01T01:00:00.000000000',
       '2001-01-01T02:00:00.000000000', '2001-01-01T03:00:00.000000000',
       '2001-01-01T04:00:00.000000000', '2001-01-01T05:00:00.000000000',
       '2001-01-01T05:00:00.000000000', '2001-01-01T06:00:00.000000000',
       '2001-01-01T07:00:00.000000000', '2001-01-01T08:00:00.000000000',
       '2001-01-01T09:00:00.000000000', '2001-01-01T10:00:00.000000000'], dtype='datetime64[ns]')

有没有一种简单的方法可以删除第二次出现的2001-01-01T05:00:00.000000000?实际问题涉及多维NetCDF文件,因此切换到Pandas不是选择。[更新]我得到的最接近的答案是遵循这个答案; 只要不使用Dask,这对我的简单示例有效,如果文件包含Dask数组,则会出现错误:

'last' with skipna=True is not yet implemented on dask arrays

但我不知道在哪里可以/必须设置skipna
2个回答

28

我认为xarray没有自己的用于此目的的方法,但以下方法可行:

In [7]: _, index = np.unique(f['time'], return_index=True)

In [8]: index
Out[8]: array([ 0,  1,  2,  3,  4,  5,  7,  8,  9, 10, 11])

In [9]: f.isel(time=index)
Out[9]: 
<xarray.Dataset>
Dimensions:  (time: 11)
Coordinates:
  * time     (time) datetime64[ns] 2001-01-01 2001-01-01T01:00:00 ...
Data variables:
   var      (time) float64 dask.array<shape=(11,), chunksize=(6,)>

非常感谢这个解决方案。我和@bart一样遇到了使用xr.open_mfdataset时重复时间条目的问题,而这个解决方案完美地解决了它。 - drg

11

显然stackoverflow不允许我评论...我想补充Keisuke的答案。你也可以使用get_index()函数获取pandas索引。

f.sel(time=~f.get_index("time").duplicated())

不起作用。返回“pandas.errors.InvalidIndexError: 仅针对唯一值索引对象重新索引”。 - Biggsy
对我来说运行良好,但这里的“~”是什么作用? - Abel
~ 是 numpy(和 xarray)中的反转运算符(https://numpy.org/doc/stable/reference/generated/numpy.invert.html)。如果应用于布尔数组,比如 duplicated 函数返回的数组,它就是 not 操作的简写。如果愿意,你也可以使用 np.logical_not 替代 ~。但是记住,你不能在其他类型的数组中将 ~ 用作 np.logical_not 的替代品,所以请小心使用;-) - Mark Boer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接