xarray select only the timesteps which are the first of the month

Viewed 1422

I want to select only the timesteps where the data is the first of the month. The reason being is that for the dates that are not the first day of the month the data is all nan.

Make the dummy dataset:

times = [
    pd.to_datetime('2017-01-01'),
    pd.to_datetime('2017-01-31'),
    pd.to_datetime('2017-02-01'),
    pd.to_datetime('2017-02-02'),
    pd.to_datetime('2017-03-01'),
    pd.to_datetime('2017-03-29'),
    pd.to_datetime('2017-03-30'),
    pd.to_datetime('2017-04-01'),
]
data = np.ones((8, 3, 3))
data[[1, 3, 5, 6], :, :] = np.nan

lat = [0, 1, 2]
lon = [0, 1, 2]


ds = xr.Dataset(
    {'data': (['time', 'lat', 'lon'], data)},
    coords={
        'lon': lon,
        'lat': lat,
        'time': times,
    }
)

ds

Out[]:
<xarray.Dataset>
Dimensions:  (lat: 3, lon: 3, time: 8)
Coordinates:
  * lon      (lon) int64 0 1 2
  * lat      (lat) int64 0 1 2
  * time     (time) datetime64[ns] 2017-01-01 2017-01-31 ... 2017-04-01
Data variables:
    data     (time, lat, lon) float64 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0

Ideally I want an output that selects only the [0, 2, 4, 7] indexed times.

<xarray.Dataset>
Dimensions:  (lat: 3, lon: 3, time: 4)
Coordinates:
  * lon      (lon) int64 0 1 2
  * lat      (lat) int64 0 1 2
  * time     (time) datetime64[ns] 2017-01-01 2017-02-01 2017-03-01 2017-04-01
Data variables:
    data     (time, lat, lon) float64 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0
2 Answers

Using where with drop=True is an approach that works, but perhaps the most direct way of doing this is to use sel in combination with a boolean DataArray:

ds.sel(time=ds.time.dt.day == 1)

<xarray.Dataset>
Dimensions:  (lat: 3, lon: 3, time: 4)
Coordinates:
  * lon      (lon) int64 0 1 2
  * lat      (lat) int64 0 1 2
  * time     (time) datetime64[ns] 2017-01-01 2017-02-01 2017-03-01 2017-04-01
Data variables:
    data     (time, lat, lon) float64 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0

The way that I had working so far uses the xarray .where() combined with the square-bracket time subsetting functionality:

ds.where(ds['time.day'] == 1, drop=True)


<xarray.Dataset>
Dimensions:  (lat: 3, lon: 3, time: 4)
Coordinates:
  * lon      (lon) int64 0 1 2
  * lat      (lat) int64 0 1 2
  * time     (time) datetime64[ns] 2017-01-01 2017-02-01 2017-03-01 2017-04-01
Data variables:
    data     (time, lat, lon) float64 1.0 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0 1.0
Related