代码之家  ›  专栏  ›  技术社区  ›  Bart

在xarray中删除重复次数

  •  1
  • Bart  · 技术社区  · 8 年前

    我正在用 open_mfdataset ,其中包含重复的时间。对于每次重复的时间,我只想保留第一次出现的时间,而删除第二次出现的时间(这种情况永远不会发生得更频繁)。这个问题与 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是没有选择的。

    [更新] 我得到的最接近的是 this answer ;对于我的简单示例,只要不使用dask,如果文件包含dask数组,就会出现错误:

    skipna=true的“last”尚未在DASK数组上实现

    但我看不出我能/必须去哪里 skipna 是的。

    1 回复  |  直到 8 年前
        1
  •  8
  •   Keisuke FUJII    8 年前

    我认为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,)>