Hamza Waheed
Hamza Waheed

Reputation: 155

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

I'm trying to slice some netCDF data for climate projections and having some trouble with selecting the longitude and latitude values.

Here is what the dataset looks like.

In [49]: dataSet
Out[49]: 
<xarray.Dataset>
Dimensions:    (bnds: 2, time: 60, x: 253, y: 167)
Coordinates:
  * time       (time) object 2016-01-16 12:00:00 ... 2020-12-16 12:00:00
    lon        (y, x) float64 ...
    lat        (y, x) float64 ...
  * x          (x) float64 -6.3e+06 -6.25e+06 -6.2e+06 ... 6.25e+06 6.3e+06
  * y          (y) float64 -4.15e+06 -4.1e+06 -4.05e+06 ... 4.1e+06 4.15e+06
    height     float64 ...
Dimensions without coordinates: bnds
Data variables:
    time_bnds  (time, bnds) object ...
    tasmax     (time, y, x) float32 ...
    crs        |S1 ...

When I try to get temperature values from this data based on certain geographical coordinates I get this error.

In [50]: dataSet.sel(lon='71.560135', lat='34.025917', time='2018-07-01', method='nearest').data[0]

Traceback (most recent call last):

  File "<ipython-input-50-c0ee548ca1df>", line 1, in <module>
    dataSet.sel(lon='71.560135', lat='34.025917', time='2018-07-01', method='nearest').data[0]

  File "D:\Anaconda\lib\site-packages\xarray\core\dataset.py", line 2006, in sel
    self, indexers=indexers, method=method, tolerance=tolerance

  File "D:\Anaconda\lib\site-packages\xarray\core\coordinates.py", line 380, in remap_label_indexers
    obj, v_indexers, method=method, tolerance=tolerance

  File "D:\Anaconda\lib\site-packages\xarray\core\indexing.py", line 259, in remap_label_indexers
    dim_indexers = get_dim_indexers(data_obj, indexers)

  File "D:\Anaconda\lib\site-packages\xarray\core\indexing.py", line 225, in get_dim_indexers
    raise ValueError("dimensions or multi-index levels %r do not exist" % invalid)

ValueError: dimensions or multi-index levels ['lon', 'lat'] do not exist

The lat and lon values(arrays?) inside the data set look something like this

In [51]: dataSet.lat.values
Out[51]: 
array([[-25.2261467 , -25.13259315, -25.03960228, ..., -25.03960228,
        -25.13259315, -25.2261467 ],
       [-24.86881447, -24.77511597, -24.68197823, ..., -24.68197823,
        -24.77511597, -24.86881447],
       [-24.50981522, -24.41597176, -24.32268715, ..., -24.32268715,
        -24.41597176, -24.50981522],
       ...,
       [ 41.7208252 ,  41.83537292,  41.94952393, ...,  41.94952393,
         41.83537292,  41.7208252 ],
       [ 42.0737381 ,  42.1884079 ,  42.3026886 , ...,  42.3026886 ,
         42.1884079 ,  42.0737381 ],
       [ 42.42486954,  42.53966904,  42.65407944, ...,  42.65407944,
         42.53966904,  42.42486954]])

In [52]: dataSet.lon.values
Out[52]: 
array([[ 20.79260826,  21.18661499,  21.58048439, ..., 118.41951752,
        118.81338501, 119.20738983],
       [ 20.68895531,  21.08365822,  21.47822571, ..., 118.52177429,
        118.91634369, 119.31104279],
       [ 20.58544159,  20.98083687,  21.37609863, ..., 118.62390137,
        119.01916504, 119.41455841],
       ...,
       [  2.21267986,   2.68719077,   3.16272235, ..., 136.83728027,
        137.31280518, 137.787323  ],
       [  2.05844355,   2.53320289,   3.00899577, ..., 136.99099731,
        137.46679688, 137.94155884],
       [  1.90317976,   2.3781817 ,   2.85422993, ..., 137.14576721,
        137.62181091, 138.09681702]])

I'd really appreciate any help on this, I need to extract the data from either this or use non-downgraded models which might hamper the efficacy of my other results.

Upvotes: 2

Views: 4825

Answers (2)

Ruben Calje
Ruben Calje

Reputation: 71

Like Maximilian pointed out, lon and lat are non-dimension coordinates. The dimensions you can use in .sel of your dataset are x, y and time. So you have to calculate the x and y coordinates corresponding to your lon and lat. You can do this with the following code (not tested), approximately:

import numpy as np
# calculate distance (no sqrt as we are only interested in the location of the minimum)
d = ((dataset.lon - 71.560135) ** 2 + (dataset.lat - 34.025917) ** 2).values
row, col = np.unravel_index(np.argmin(d), d.shape)
dataSet.sel(x=dataset.x[col], y=dataset.y[row], time='2018-07-01', method='nearest')

We hereby make the mistake to use a distance calculation for a rectangular coordinate system on a spherical coordinate system, but we are approximately right. You can change the calculation of d if this bothers you.

Upvotes: 0

Maximilian
Maximilian

Reputation: 8530

.sel requires dimension names rather than non-dimension coordinates. You could use .where to filter by coordinate values if needed

Upvotes: 2

Related Questions