Search code examples
pythonslicenetcdfpython-xarray

Xarray: slicing latitude longitude using dimension name


I am writing a program that will open Meteorological NetCDF data, slice it for a given region and then do some calculations, for example:

data =xr.open_dataset(SomeFile)

SlicedData = data.sel(lat=slice(max_lat,min_lat),
                lon=slice(min_lon,max_lon))
ExampleResult = SlicedData.mslp.average('lon')

Here follows an example of how 'data' might be scrtuctured:

<xarray.Dataset>
Dimensions:  (lon: 144, lat: 37, level: 17, time: 25)
Coordinates:
  * lon      (lon) float32 -180.0 -177.5 -175.0 -172.5 ... 172.5 175.0 177.5
  * lat      (lat) float32 0.0 -2.5 -5.0 -7.5 -10.0 ... -82.5 -85.0 -87.5 -90.0
  * level    (level) float32 1e+03 925.0 850.0 700.0 ... 50.0 30.0 20.0 10.0
  * time     (time) datetime64[ns] 2011-05-25 2011-05-25T06:00:00 ... 2011-05-31
Data variables:
    air      (time, level, lat, lon) float32 ...
    hgt      (time, level, lat, lon) float32 ...
    rhum     (time, level, lat, lon) float32 ...
    omega    (time, level, lat, lon) float32 ...
    uwnd     (time, level, lat, lon) float32 ...
    vwnd     (time, level, lat, lon) float32 ...
    mslp     (time, lat, lon) float32 ... 

However, distinct data sources store the latitude and longitude coordinates using different indexers: it could be, for example, either latitude/longitude or lat/lon. So, for example, if the indexers used are latitude/longitude, the following:

SlicedData = data.sel(lat=slice(max_lat,min_lat),
                    lon=slice(min_lon,max_lon))

Would return:

KeyError: 'lat is not a valid dimension or coordinate' 

Is there a way I can slice the data using Xarray using a string for the coordinate indexer? For example:

LatIndexer, LonIndexer = 'lat', 'lon'
SlicedData = data.sel(LatIndexer=slice(max_lat,min_lat),
                        LonIndexer=slice(min_lon,max_lon))

Solution

  • Just pass by dictionary:

    LatIndexer, LonIndexer = 'lat', 'lon'
    SliceData = data.sel(**{LatIndexer: slice(max_lat, min_lat),
                            LonIndexer: slice(max_lon, min_lon)})
    

    Alternatively

    LatIndexer, LonIndexer = 'lat', 'lon'
    SliceData = data.loc[{LatIndexer: slice(max_lat, min_lat),
                          LonIndexer: slice(max_lon, min_lon)}]
    

    Reference Indexing and selecting data