Преобразование набора данных Netcdf из секунд с момента начала в часы UTC

Я работаю с кодом формата netcdf, и мне нужно преобразовать время из секунд от времени начала (2016-01-01 00:00:00.0) во время в формате UTC. Я довольно новичок во всем этом, поэтому я действительно борюсь!

Я пытался использовать num2date из netCDF4.

from netCDF4 import date2num , num2date, Dataset
time=f.variables['time'][:]
dates=netCDF4.num2date(time[:],time.units)
print(dates.strftime('%Y%m%d%H') for date in dates)

AttributeError: объект «MaskedArray» не имеет атрибута «единицы»


person wam_salley    schedule 30.09.2019    source источник


Ответы (1)


Поскольку вы извлекаете time из переменных в time=f.variables['time'][:], он потеряет связанную с ним единицу (время - это просто замаскированный массив, как говорит ошибка). То, что вы должны передать num2date(), это variables['time'].units, например.

from netCDF4 import date2num, num2date, Dataset
file = ... # your nc file

with Dataset(file) as root:
    time = root.variables['time'][:]
    dates = num2date(time, root.variables['time'].units)
    ## directly get UTC hours here:
    # unit_utchours = root.variables['time'].units.replace('seconds', 'hours')
    ## would e.g. be 'hours since 2019-08-15 00:00:00'
    # utc_hours = date2num(dates, unit_utchours)

# check:
print(dates[0].strftime('%Y%m%d%H'))
# e.g. prints 2019081516

... чтобы получить даты в виде числа, вы можете, например. делать

num_dates = [int(d.strftime('%Y%m%d%H')) for d in dates]
# replace int with float if you need floating point numbers etc.

... чтобы получить даты в часах UTC, см. раздел с комментариями в первом блоке кода. Поскольку массив дат содержит объекты типа datetime.datetime, вы также можете сделать

utc_hours = [d.hour+(d.minute/60)+(d.second/3600) for d in dates]
person MrFuppes    schedule 01.10.2019
comment
только что нашел очень похожий вопрос, на который уже был дан ответ здесь. - person MrFuppes; 01.10.2019
comment
Когда я это делаю, я получаю эту ошибку 'KeyError: ‹class 'netCDF4._netCDF4.Variable'› float64 time(time) standard_name: единицы времени: секунды с 01-01-2016 00:00:00.0 UTC неограниченные размеры: текущее время shape = (103384,) заполнение включено, по умолчанию используется _FillValue 9,969209968386869e+36 ' - person wam_salley; 01.10.2019
comment
какая строка выдает ошибку? time = ... или dates = ...? если это второе, вы можете попробовать использовать time.data - person MrFuppes; 01.10.2019
comment
это время =… Я думаю, что это может быть связано с тем, что это поплавок, но я действительно не уверен - person wam_salley; 01.10.2019
comment
хм ... если это действительно эта строка, ошибка также должна быть выдана в версии кода, который вы разместили в вопросе (в time=f.variables['time'][:]). Формат float в порядке, кстати. - person MrFuppes; 01.10.2019
comment
Я заставил его работать, но он дает мне очень странные значения, когда я рисую его как 0001-01-18, когда он должен быть 2016-07-18 в 16:39:41. - person wam_salley; 01.10.2019
comment
Звучит странно, но без файла примера сложно сказать. Если поделитесь файлом, могу глянуть. - person MrFuppes; 01.10.2019
comment
На самом деле я заставил его работать, однако это единственное чтение для одного индекса, как мне заставить его читать для всего массива? - person wam_salley; 02.10.2019
comment
ты имеешь в виду print(dates[0].strftime('%Y%m%d%H'))? Я просто поместил эту строку туда, чтобы увидеть, в порядке ли вывод. он просто печатает dates по индексу 0. чтобы напечатать все строки, сделайте, например. for d in dates: print(d.strftime('%Y%m%d%H')) - person MrFuppes; 02.10.2019
comment
да! Мне действительно нужно время в десятичных дробях, чтобы построить его правильно. - person wam_salley; 02.10.2019
comment
И последний вопрос, мне нужны данные в формате (Ч+(М/60)+(секунды/3600)). Как бы я преобразовал это в это? Я хочу выяснить это, потому что это только один из моих наборов данных из многих. Я могу сделать это вручную, но я не хочу делать это каждый раз. - person wam_salley; 02.10.2019
comment
Кроме того, вы были очень полезны! - person wam_salley; 02.10.2019
comment
вы имеете в виду часы UTC? Я добавил два варианта, как получить их в свой ответ. вы можете либо получить его с помощью функции date2num из пакета netCDF, либо запустить другое понимание списка. Я бы сказал, что netcdf — не самый простой формат данных для начала работы, поэтому я рад, если смог помочь. Как только вы привыкнете к этому, это довольно приятный формат ;-) - person MrFuppes; 02.10.2019