本文介绍了Xarray:无尺寸的切片坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使看起来很简单,我也很难解决这个问题.

I am having difficultly with this topic, even though it seems like it should be rather simple.

我想使用一组经度和纬度坐标来切片xarray数据集.

I want to slice an xarray dataset using a set of latitude and longitude coordinates.

这是我的数据集的样子:

Here is what my dataset looks like:

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 ...

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

But my lat/lon values are incorrect:

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 ]])

当然,如果我尝试使用经度/纬度坐标进行切片,则会因尺寸不匹配而出现错误.

Of course, if I try to slice using the lats/lons coordinates, I get an error because the dimensions don't match.

    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数据集,我的理解中是否缺少某些东西?

Is there something I am missing in my comprehension with this being a NARR dataset?

推荐答案

更新2020-04-30

如果要基于纬度和经度选择数据,则可以使用 where() 来执行以下操作:

If you want to select data based on lat and lon, you could use where() to do something like:

data.where((data.lats > 25) & (data.lats < 30) & (data.lons > -80) & (data.lons < -75))

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

You could add drop=True to return a smaller-sized dataset instead of filling the non-matching values with NA.

原始答案

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

In your first example, you are not indexing by lat/lon but by each x and y's numeric index. That is, you are slicing between the 25th and 30th y and -80th and -75th x value. This explains why the lat/lon values don't make sense in your output.

您可以使用 像这样:

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

这篇关于Xarray:无尺寸的切片坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 13:18