【问题标题】:Xarray: slice coordinates with no dimensionsXarray:没有维度的切片坐标
【发布时间】:2018-01-11 19:20:50
【问题描述】:

我很难理解这个话题,尽管它看起来应该很简单。

我想使用一组纬度和经度坐标对 xarray 数据集进行切片。

这是我的数据集的样子:

In [31]: data = xr.open_mfdataset(open_file, decode_cf=True)

In [32]: data
Out[32]: 
<xarray.Dataset>
Dimensions:  (time: 108120, x: 349, y: 277)
Coordinates:
    lons     (y, x) float64 -145.5 -145.3 -145.1 -144.9 -144.8 -144.6 -144.4 ...
    lats     (y, x) float64 1.0 1.104 1.208 1.312 1.416 1.519 1.621 1.724 ...
  * time     (time) datetime64[ns] 1980-01-01 1980-01-01T03:00:00 ...
Dimensions without coordinates: x, y
Data variables:
    stp      (time, y, x) float64 0.1235 0.0867 0.07183 0.05389 0.05901 ...

这是我要切片的操作:

In [48]: lat_bnd = [25,30]
    ...: lon_bnd = [-80,-75]

In [49]: r = data.sel(y=slice(*lat_bnd),x=slice(*lon_bnd))

一切看起来都很棒:

In [50]: r
Out[50]: 
    <xarray.Dataset>
    Dimensions:  (time: 108120, x: 5, y: 5)
    Coordinates:
        lons     (y, x) float64 -82.52 -82.28 -82.05 -81.81 -81.57 -82.44 -82.2 ...
        lats     (y, x) float64 13.54 13.46 13.38 13.3 13.22 13.77 13.69 13.61 ...
      * time     (time) datetime64[ns] 1980-01-01 1980-01-01T03:00:00 ...
    Dimensions without coordinates: x, y
    Data variables:
        stp      (time, y, x) float64 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ...

但我的纬度/经度值不正确:

In [53]: r.lats.values
Out[53]: 
array([[ 13.53542397,  13.45647916,  13.37686013,  13.296571  ,
         13.21561592],
       [ 13.76719053,  13.6878189 ,  13.60776989,  13.52704767,
         13.44565641],
       [ 13.99938176,  13.91958109,  13.83909988,  13.75794233,
         13.67611265],
       [ 14.2319952 ,  14.15176326,  14.07084762,  13.98925249,
         13.90698214],
       [ 14.46502833,  14.3843629 ,  14.30301059,  14.22097564,
         14.13826236]])

In [54]: r.lons.values
Out[54]: 
array([[-82.52229969, -82.28438922, -82.0469968 , -81.8101255 ,
        -81.57377834],
       [-82.44118948, -82.20260881, -81.96455096, -81.72701901, -81.490016  ],
       [-82.3595596 , -82.12030558, -81.8815792 , -81.64338357,
        -81.40572174],
       [-82.27740522, -82.03747469, -81.79807668, -81.55921433,
        -81.32089068],
       [-82.19472148, -81.95411126, -81.71403851, -81.47450637, -81.2355179 ]])

当然,如果我尝试使用 lats/lons 坐标进行切片,则会出现错误,因为尺寸不匹配。

    In [55]: r = data.sel(lats=slice(*lat_bnd),lons=slice(*lon_bnd))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-55-7c6237be5f22> in <module>()
----> 1 r = data.sel(lats=slice(*lat_bnd),lons=slice(*lon_bnd))

/lib/anaconda2/lib/python2.7/site-packages/xarray/core/dataset.pyc in sel(self, method, tolerance, drop, **indexers)
   1204         """
   1205         pos_indexers, new_indexes = indexing.remap_label_indexers(
-> 1206             self, indexers, method=method, tolerance=tolerance
   1207         )
   1208         result = self.isel(drop=drop, **pos_indexers)

/lib/anaconda2/lib/python2.7/site-packages/xarray/core/indexing.pyc in remap_label_indexers(data_obj, indexers, method, tolerance)
    275     new_indexes = {}
    276 
--> 277     dim_indexers = get_dim_indexers(data_obj, indexers)
    278     for dim, label in iteritems(dim_indexers):
    279         try:

/lib/anaconda2/lib/python2.7/site-packages/xarray/core/indexing.pyc in get_dim_indexers(data_obj, indexers)
    243     if invalid:
    244         raise ValueError("dimensions or multi-index levels %r do not exist"
--> 245                          % invalid)
    246 
    247     level_indexers = defaultdict(dict)

ValueError: dimensions or multi-index levels ['lons', 'lats'] do not exist

作为一个 NARR 数据集,我的理解中有什么遗漏吗?

【问题讨论】:

    标签: python xarray


    【解决方案1】:

    也许有人可能会感兴趣 - 通过使用无法从 xarray 的最近邻域插值的好功能中获利的地方。 我有一个类似的问题 - 一个以 2d 数组作为 lons/lats 坐标的曲线网格。此外,我正在寻找最接近给定点的坐标。我使用以下附加函数将“任何” lon/lat 对转换为 (x,y) 元组:

    def find_nearest(lons, lats, lon0,lat0):
       idx = ((lons - lon0)**2+(lats - lat0)**2).argmin()
       value_lat =  lats.flat[idx]
       return tuple(np.squeeze(np.where(lats2d == value_lat)))
    

    然后,将其用作:

    find_nearest(tmp.longitude.values,tmp.latitude.values, -22.16,32.3)
    

    【讨论】:

      【解决方案2】:

      2020-04-30 更新

      如果您想根据纬度和经度选择数据,您可以使用where() 执行以下操作:

      data.where((data.lats &gt; 25) &amp; (data.lats &lt; 30) &amp; (data.lons &gt; -80) &amp; (data.lons &lt; -75))

      您可以添加 drop=True 以返回较小的数据集,而不是使用 NA 填充不匹配的值。


      原答案

      在您的第一个示例中,您不是按纬度/经度索引,而是按每个xy 的数字索引。也就是说,您在第 25 个和第 30 个 y 和 -80th 和 -75th x 值之间进行切片。这解释了为什么 lat/lon 值在您的输出中没有意义。

      您可以使用xr.Dataset.set_index() 将坐标与尺寸相关联,如下所示:

      data = data.set_index(y='lats')
      data = data.set_index(x='lons')
      

      【讨论】:

      • 不幸的是,我收到以下错误:NotImplementedError: > 1 ndim Categorical 目前不支持。我有 xarray 版本 0.9.6。我的问题是 NARR 的 lats 和 lons 有两个维度(x 和 y)。这里还有其他见解吗?
      • @MariaMolina 我不熟悉 NARR 数据,也没有类似的数据集可供测试,但您可以尝试将列表传递给 set_index:类似于 data.set_index(y=['lats', 'lons'], inplace=True) 的内容跨度>
      • "inplace" 已被弃用,如下所示:github.com/pydata/xarray/issues/1756。如果您在 2D 坐标上尝试“set_index”,则会产生以下错误:“ValueError: Index data must be 1-dimensional”。如果您尝试将新索引打包到列表中,则会引发“NotImplementedError: > 1 ndim Categorical are not supported at this time”和“ValueError: Buffer has wrong number of dimensions (expected 1, got 2)”。
      • @Dan 你在这里找到解决这个问题的方法了吗?我仍在为同样的程序而苦苦挣扎。
      • @clifgray 检查我更新的答案。这能解决你的问题吗?如果不是,请指出失败的数据集和/或发布新问题。
      【解决方案3】:

      一种方法可能是根据 x,y 坐标本身进行切片。要检查这是否满足您的域要求,您可以查看快速绘图并调整 x、y 值以进行相应的切片。但是,更好的方法是将您的 lat lon 转换为 x,y 坐标,然后根据相应的 x,y 进行切片。

      【讨论】:

      • 尊敬的 user1168337,您的建议很重要。然而,如何将 lat/lon 坐标转换为 netcdf_xarray x,y ?你能发布一个实际的例子吗?此致。
      猜你喜欢
      • 2019-06-28
      • 2021-12-03
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      • 1970-01-01
      • 1970-01-01
      • 2020-10-08
      相关资源
      最近更新 更多