I am reading a NetCDF (time, level, lat, lon) file with xarray. I am selecting two slices over level with the same size. I am wondering when I am doing an addition of the two files.
The resulting file is not giving the right dimension.
slice1 -> (72, 22 , 41, 36)
slice2 -> (72, 22 , 41, 36)
result -> (72, 21 , 41, 36)
What is wrong?
Here code that I am using
import xarray as xr
fname = "DJF_uvwq_lev_monhourly_2017.nc"
ds = xr.open_dataset(fname)
u = ds['u']
level = ds['level']
a = u.isel(level=slice(0, len(plev)-1))
b = u.isel(level=slice(1, len(plev)))
fluxInterp = a + b
print(np.shape(a))
print(np.shape(b))
print(np.shape(fluxInterp))
Unlike numpy, which aligns data based on the position in the array, xarray uses labels along a given dimension to align the data when performing data operations. Therefore, having offset labels as in the case of a
and b
along the level dimension will not perform the way you're expecting.
Setting up a dummy example:
In [1]: import xarray as xr, pandas as pd, numpy as np
In [2]: u = xr.DataArray(np.arange(5), dims=['level'], coords=[list('abcde')])
In [3]: u
Out[3]:
<xarray.DataArray (level: 5)>
array([0, 1, 2, 3, 4])
Coordinates:
* level (level) <U1 'a' 'b' 'c' 'd' 'e'
When looking at a and b in your example, you're slicing the data using an offset ( slice(0, length-1)
vs slice(1, length)
). When you do this, notice that the indices of "level" are no longer aligned:
In [4]: a = u.isel(level=slice(0, len(u.level)- 1))
...: b = u.isel(level=slice(1, len(u.level)))
In [5]: a
Out[5]:
<xarray.DataArray (level: 4)>
array([0, 1, 2, 3])
Coordinates:
* level (level) <U1 'a' 'b' 'c' 'd'
In [6]: b
Out[6]:
<xarray.DataArray (level: 4)>
array([1, 2, 3, 4])
Coordinates:
* level (level) <U1 'b' 'c' 'd' 'e'
When adding the two, or in any operation that involves broadcasting & automatic alignment (see the docs references below), missing values will be dropped from the result. Furthermore, in the results, note that the sum is the elementwise-sum where each element is aligned based on the label (b + b, c + c, d + d), not based on position (b + a, c + b, d + c).
In [7]: a + b
Out[7]:
<xarray.DataArray (level: 3)>
array([2, 4, 6])
Coordinates:
* level (level) <U1 'b' 'c' 'd'
What you're looking for is to first use the shift
method to shift the axis labels, so that the coordinate labels are aligned before you do the addition:
In [10]: c = u.shift(level=-1)
In [11]: c
Out[11]:
<xarray.DataArray (level: 5)>
array([ 1., 2., 3., 4., nan])
Coordinates:
* level (level) <U1 'a' 'b' 'c' 'd' 'e'
In [12]: a + c
Out[12]:
<xarray.DataArray (level: 4)>
array([1., 3., 5., 7.])
Coordinates:
* level (level) <U1 'a' 'b' 'c' 'd'
Now, when you add across a + c
the coordinates line up in the way you'd like.
For more information, see the xarray Computation docs on broadcasting by dimension name and automatic alignment .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.