Thomas
Thomas

Reputation: 491

How do I slice a range that occur every nth time?

I have a nc file in which the time variable is a bit weird. It is not a gregorian calendar but a simple 365-day-a-year calendar (i.e. leap years are not included). This means the unit is also a bit off, but nothing too worrisome.

xarray.DataArray 'days' (time: 6570)>
array([730817., 730818., 730819., ..., 737384., 737385., 737386.])
Dimensions without coordinates: time
Attributes:
    units:      days_since_Jan11900
    long_name:  calendar_days

730817 represents 01-01-2001 and 737386 represents 31-12-2018

I want to obtain a certain time period of the data set for multiple years, just as you can do with cdo -seldmonth, -selday etc. But of course, with no date, I cannot use the otherwise brilliant option. My idea was to slice the time range I need with np.slice, but I do not know how and cannot seem to find adequate answers on SO. In my specific case, I need to slice a range going from May 30th (150th day of the year) to Aug 18th (229th day of the year) every year. I know the first slice should be something like:

ds = ds.loc[dict(time = slice(149,229))]

But, that will only give me the range for 2001, and not the following years.

I cannot do it with cdo -ntime as it does not recognize the time unit.

How do I make sure that I get the range for the following 17 years too? And by that skipping 285 days in between the ranges I need?

Upvotes: 0

Views: 366

Answers (2)

ClimateUnboxed
ClimateUnboxed

Reputation: 8085

From your answer it seems you know the timeslices, so you could also extract them with cdo using

cdo seltimestep,149/229 in.nc out.nc 

etc

but if you want to do it (semi)automatically with cdo, it should also be possible as cdo supports a 365 day calendar. I think you need to set the calendar to this type and then probably reset the time units and the reftime. without an example file I can't test this, but I think something like this could work:

step 1: set the calendar type to 365 and then set the reference data to your first date:

cdo setcalendar,365_day infile.nc out1.nc
cdo setreftime,2000-01-01,00:00:00 out1.nc out2.nc 

you then need to see what the first date is in the file, you can pipe it to less:

cdo showdate out2.nc | less 

step 2: you then can shift the timeaxis to the correct date using cdo,shifttime

e.g. if the showdate gives the first day as 2302-04-03, then you can simply do

cdo shiftime,-302years -shifttime,-3months -shifttime,-2days out2.nc out3.nc 

to correct the dates...

Then you should be able to use all the cdo functionality on the file to do the manipulation as you wish

Upvotes: 0

Thomas
Thomas

Reputation: 491

I fixed it through Python. It can probably be done in a smarter way, but I manually picked the ranges I needed with help from @dl.meteo and using np.r_.

ds = ds.sel(time=np.r_[149:229,514:594,879:959,1244:1324,1609:1689,1974:2054,2339:2419,2704:2784,3069:3149,3434:3514,3799:3879,4164:4244,4529:4609,4894:4974,5259:5339,5624:5704,5989:6069,6354:6434])

Upvotes: 1

Related Questions