CMIP6中cftime.DatetimeJulian转换为datetime

背景

在很多CMIP6的模式数据中,时间储存都是采用的cftime的格式,而python对这种格式的时间支持并不是很友好。因此在后需的处理中需要转换cftime为datetime

核心代码

这一段代码本意就是从cftime中逐个提取年月日,时分秒信息,然后再使用datetime函数重新组装。并且这个代码输入的cftime_obj必须是单个的不能是list

import cftime
from datetime import datetime

def convert_cftime_to_datetime(cftime_obj):
    year = cftime_obj.year
    month = cftime_obj.month
    day = cftime_obj.day
    hour = getattr(cftime_obj, 'hour', 0)
    minute = getattr(cftime_obj, 'minute', 0)
    second = getattr(cftime_obj, 'second', 0)

    return datetime(year=year, month=month, day=day,
                    hour=hour, minute=minute, second=second)

完整示例

本次测试使用的CMIP6文件为:sfo3_AERhr_CESM2-WACCM_ssp126_r1i1p1f1_gn_201501010000-202412312300.nc
大家可以自行在CMIP6官网下载
大家下载好的文件可以直接放到同一个文件夹下,例如:F:\CMIP6(文件路径按需自行修改)代码中的变量名称:sfo3lat等请根据实际的变量名称修改!!!
随后只需要运行本程序即可

import os
import pandas as pd
import numpy as np
import xarray as xr
import cftime
import warnings
warnings.filterwarnings("ignore")
from datetime import datetime

def convert_cftime_to_datetime(cftime_obj):
    year = cftime_obj.year
    month = cftime_obj.month
    day = cftime_obj.day
    hour = getattr(cftime_obj, 'hour', 0)
    minute = getattr(cftime_obj, 'minute', 0)
    second = getattr(cftime_obj, 'second', 0)

    return datetime(year=year, month=month, day=day,
                    hour=hour, minute=minute, second=second)
path = r'F:\CMIP6/'
FileList = os.listdir(r'F:\CMIP6/')
for i in range(len(FileList)):  
    print("正在处理:{}".format(FileList[i]))
    ds = xr.open_dataset(r'F:\CMIP6/'+FileList[i]) 
    sfo3 = ds['sfo3'].values
    # 判断日期格式
    if isinstance(ds['time'].values[0], cftime.datetime):
    # 如果是cftime格式那么遍历每一个时间节点并转为datetime格式
        time = []
        for j in range(len(ds['time'].values)):
            time_tmp = convert_cftime_to_datetime(ds['time'].values[j])
            time.append(time_tmp)
        time = pd.to_datetime(time)
    else:
    #如果不是cftime格式,那么直接使用pandas的to_datetime函数
        time = ds['time'].values
        time = pd.to_datetime(time)  # 直接转换为pandas datetime
    try:
        lat = ds['lat'].values
        lon = ds['lon'].values
    except:
        lat = ds['latitude'].values
        lon = ds['longitude'].values
    ds.close()
    ds_new = xr.Dataset(data_vars={'sfo3': (('time', 'lat', 'lon'), sfo3)},
                       coords={'time': time, 'lat': lat, 'lon': lon})
    ds_new['sfo3'].attrs['units'] = 'ug/m3'
    ds_new['lat'].attrs['units'] = 'degrees_north'
    ds_new['lon'].attrs['units'] = 'degrees_east'
    ds_new.to_netcdf(r'F:\CMIP6_DELED/' + FileList[i]) # 设置输出文件路径


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷心没有菜

你若晌饭便是义父!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值