删除 xarray 中的重复时间

Posted

技术标签:

【中文标题】删除 xarray 中的重复时间【英文标题】:Drop duplicate times in xarray 【发布时间】:2018-12-06 02:09:01 【问题描述】:

我正在读取带有 open_mfdataset 的 NetCDF 文件,其中包含重复的时间。对于每个重复时间,我只想保留第一次出现,并删除第二次(它永远不会更频繁地出现)。该问题与this Pandas question 非常相似,但那里提供的解决方案似乎都不适用于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'])

生成的dataset 中的时间为:

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。

[update] 我得到的最接近的是关注this answer;只要不使用 Dask,这适用于我的简单示例,如果文件包含 Dask 数组,我会收到错误:

'last' with skipna=True 尚未在 dask 数组上实现

但我看不出我可以/必须在哪里设置skipna

【问题讨论】:

【参考方案1】:

我认为 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 重复的时间条目,这个解决方案完美地解决了它。【参考方案2】:

显然***不会让我评论......我想补充Keisuke的答案。您还可以使用get_index() 函数获取pandas 索引。

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

【讨论】:

不起作用。返回pandas.errors.InvalidIndexError: Reindexing only valid with uniquely valued Index objects 对我来说很好,但是 '~' 在这里做什么? ~ 是 numpy(和 xarray)(numpy.org/doc/stable/reference/generated/numpy.invert.html)中的反转运算符。如果在布尔数组上使用,例如由重复函数返回的数组,它是not 操作的简写。如果您愿意,也可以使用 np.logical_not 代替 ~。您不能使用 ~ 代替任何其他类型的数组的 np.logical_not,所以要小心 ;-)

以上是关于删除 xarray 中的重复时间的主要内容,如果未能解决你的问题,请参考以下文章

删除表格中的重复单元格

删除列表python中的重复项[重复]

基于MySql中的两列删除重复记录[重复]

从c中的struct数组中删除重复名称[重复]

如何删除商店extjs中的重复值

基于R中的两列删除重复项[重复]