создать netcdf с помощью xarray с отметкой времени после 2263 года

Есть ли способ создать файл netCDF с измерением времени после 2263 года с использованием xarray?

Вот как можно создать игрушечный набор данных netCDF http://xarray.pydata.org/en/stable/time-series.html

Однако измерение времени имеет тип индекса даты и времени pandas, и они не выходят за пределы 2263, как можно увидеть здесь: https://github.com/pandas-dev/pandas/issues/13346


person user308827    schedule 21.04.2018    source источник
comment
Примечание. При декодировании/кодировании даты и времени для нестандартных календарей или дат до 1678 года или после 2262 года xarray использует библиотеку netcdftime. netcdftime ранее поставлялся с пакетом netcdf4-python, но теперь распространяется отдельно. netcdftime — необязательная зависимость от xarray.   -  person Severin Pappadeux    schedule 24.04.2018
comment
спасибо @SeverinPappadeux, я получаю сообщение об ошибке даже после установки netcdftime с помощью pip install cftime   -  person user308827    schedule 24.04.2018
comment
@ user308827, можете ли вы добавить код, который вы использовали, к самому вопросу?   -  person Tarun Lalwani    schedule 24.04.2018
comment
Поскольку в этом году эта страница будет занимать первые места в рейтинге, оставьте здесь ссылку для будущих читателей: youtube.com /watch?v=dQw4w9WgXcQ   -  person NVRM    schedule 27.04.2018


Ответы (2)


В будущем вы, возможно, сможете сделать это, создав ось дат с использованием cftime объектов, но в настоящее время существует нерешенная проблема в xarray, которая не позволяет вам писать файлы netCDF, содержащие такие объекты.

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

import numpy as np
import xarray as xr

days = np.asarray(range(100*365))

ds = xr.Dataset(
    {'time': (['time'], days, {'units': 'days since 2200-01-01 0:0:0'})}
)

print(ds['time'][-1]

ds.to_netcdf('test.nc')
ds = xr.open_dataset('test.nc')
print(ds['time'][-1])

дает результат

<xarray.DataArray 'time' ()>
array(36499)
Coordinates:
    time     int64 36499
Attributes:
    units:    days since 2200-01-01 0:0:0

с последующим

<xarray.DataArray 'time' ()>
array(datetime.datetime(2299, 12, 7, 0, 0), dtype=object)
Coordinates:
    time     object 2299-12-07

Обратите внимание, что при повторном открытии набора данных xarray автоматически его декодирует.

Используемый атрибут 'units' должен соответствовать условиям CF. для временных координат. Вы можете заменить «дни» на «часы», «минуты» или «секунды» по своему усмотрению.

Это требует, чтобы вы вручную вычисляли необходимые целые числа, что в основном сложно, если ваша ось времени указана в годах (поскольку «год» не является определенной единицей измерения времени, его длина варьируется в зависимости от високосных лет). Если это так, вы можете использовать что-то вроде следующего:

import cftime

# replace this to use a different calendar
Datetime = cftime.DatetimeProlepticGregorian

# make your list of Datetime objects
time_list = []
month = day = 1
hour = minute = second = 0
for year in range(2200, 2300, 1):
    time_list.append(Datetime(year, month, day, hour, minute, second))

# this will convert them into a time axis, here in units of
# 'days since 2200-01-01 0:0:0'
seconds_in_day = 60*60*24
day_list = []
for dt in time_list:
    time_since_2200 = dt - Datetime(2200, month, day, hour, minute, second)
    day_list.append(int(time_since_2200.total_seconds() / seconds_in_day))

Вы можете использовать другой класс cftime (например, cftime.DatetimeJulian или cftime.DatetimeNoLeap), чтобы использовать другой календарь. Этот код следует изменить, чтобы дать право time_list для вашего использования. Вы также можете отключить seconds_in_day для секунд в какой-либо другой единице времени (а также указать эту единицу для вызова xr.Dataset).

person Jeremy McGibbon    schedule 25.04.2018

Проблема может заключаться в том, что xarray необязательно использует netcdftime для времени вне диапазона datetime.datetime, а pandas — нет. Итак, что-то вроде этого примера не будет работать, даже если установлен netcdftime.

import numpy as np
import pandas as pd
import xarray as xr
data = np.random.rand(4, 3)
locs = ['IA', 'IL', 'IN']
times = pd.date_range('2318-04-25', periods=4)
da = xr.DataArray(data, coords=[times, locs], dims=['time', 'space'])

Это не удастся, когда вы попытаетесь создать pandas date_range. Даже предоставление netcdftime.datetime в качестве первого аргумента pd.date_range() не работает, потому что pandas хочет преобразовать в свой собственный ограниченный тип даты и времени.

Вместо этого вам нужно указать время непосредственно в xarray. К сожалению, здесь меня подводит мое знание netcdf, но я могу дать вам общие сведения, и, возможно, вы сможете получить их отсюда.

Есть много способов указать даты в параметрах DataArray. Вам нужно создать свой собственный диапазон дат с типом netcdftime.datetime в качестве его основы. Вы можете создать индекс даты с помощью netcdftime.date2index() и использовать его вместо панд DateIndex в приведенном выше примере.

Вероятно, вам следует опубликовать свой пример кода, который показывает проблему. Я предположил, что вы пытаетесь создать DataArray, но, возможно, это не та проблема, с которой вы столкнулись.

person Brad Dre    schedule 25.04.2018