Как мне нарезать диапазон, который встречается каждый n-й раз?

#python #netcdf #python-xarray #cdo-climate

#python #netcdf #python-xarray #cdo-климат

Вопрос:

У меня есть nc файл, в котором переменная времени немного странная. Это не григорианский календарь, а простой календарь на 365 дней в году (т. Е. високосные годы не включены). Это означает, что устройство также немного отключено, но ничего слишком тревожного.

 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 представляет 01-01-2001 и 737386 представляет 31-12-2018

Я хочу получить определенный период времени для набора данных за несколько лет, так же, как вы можете сделать с cdo -seldmonth, -selday etc. Но, конечно, без даты я не могу использовать другой блестящий вариант. Моя идея состояла в том, чтобы нарезать нужный мне временной диапазон np.slice , но я не знаю, как это сделать, и, похоже, не могу найти адекватных ответов на SO. В моем конкретном случае мне нужно нарезать диапазон с 30 мая (150-й день года) по 18 августа (229-й день года) каждый год. Я знаю, что первый фрагмент должен быть чем-то вроде:

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

Но это даст мне диапазон только за 2001 год, а не за последующие годы.

Я не могу этого сделать, cdo -ntime поскольку он не распознает единицу времени.

Как мне убедиться, что я получу диапазон и для следующих 17 лет? И тем самым пропуская 285 дней между нужными мне диапазонами?

Комментарии:

1. Дорогой Томас, ты пробовал ds.sel(time=[149, 229]) ? Возможно, вам нужно установить time в качестве координаты. xarray.pydata.org/en/stable/indexing.html

2. Привет @dl.meteo. Спасибо за ваш ответ! Он также работает с ручным выбором каждого нужного мне диапазона, следовательно, пропуская 285 дней между диапазонами. Спасибо!

Ответ №1:

Я исправил это с помощью Python. Вероятно, это можно сделать более разумным способом, но я вручную выбрал нужные мне диапазоны с помощью @dl.meteo и 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])
  

Ответ №2:

Из вашего ответа кажется, что вы знаете временные интервалы, поэтому вы также можете извлечь их с помощью cdo, используя

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

и т. д

но если вы хотите сделать это (полу) автоматически с помощью cdo, это также должно быть возможно, поскольку cdo поддерживает календарь на 365 дней. Я думаю, вам нужно установить календарь на этот тип, а затем, вероятно, сбросить единицы измерения времени и время ссылки. без файла примера я не могу это протестировать, но я думаю, что что-то подобное может сработать:

шаг 1. установите для типа календаря значение 365, а затем установите для справочных данных вашу первую дату:

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

затем вам нужно посмотреть, какая первая дата в файле, вы можете передать ее в меньшее:

 cdo showdate out2.nc | less 
  

шаг 2: затем вы можете сдвинуть ось времени на правильную дату, используя cdo, shifttime

например, если дата показа указывает первый день как 2302-04-03, тогда вы можете просто сделать

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

чтобы исправить даты…

Тогда вы должны иметь возможность использовать все функции cdo в файле, чтобы выполнять манипуляции по своему усмотрению