在python中的netcdf文件上计算几年的年度异常

时间:2018-09-23 02:31:49

标签: python python-2.7 netcdf

我需要使用一些功能来计算44年的netcdf每月文件的气温的月度,季节和年度异常,该功能可以让我自动获取月度,季节和年度期间的异常并将结果保存在文件夹中。我只知道如何使用它,但要使用该功能只能使用一年而不是几年。

from netCDF4 import Dataset, num2date
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeat
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from mpl_toolkits.basemap import Basemap

ds = Dataset('./interim_t2m_19792017.nc')
lats = ds.variables['latitude'][:]  # extract/copy the data
lons = ds.variables['longitude'][:]
time = ds.variables['time']
var = ds.variables['t2m'] 

lon, lat = np.meshgrid(lons, lats)
dates = num2date(time[:], time.units)
dates_pd = pd.to_datetime(dates)
periods = dates_pd.to_period(freq='M')

def plt_map(data):
    m = Basemap(projection='mill',llcrnrlat=-80,urcrnrlat=80,\
            llcrnrlon=0,urcrnrlon=360,lat_ts=20,resolution='c')
    x, y = m(lon, lat)
    plt.figure(figsize=(10,7))
    m.drawcoastlines()
    m.drawparallels(np.arange(-80.,81.,20.))
    m.drawmeridians(np.arange(-180.,181.,20.))
    m.drawmapboundary(fill_color='white')
    m.contourf(x,y,data, extend="both",cmap="jet");
    plt.colorbar(orientation='horizontal', pad=0.05)
plt_map(var[0,:,:])

mask_2016 = periods.year==2016
data = var[mask_2016,:,:].mean(axis=0)
plt_map(data)

3 个答案:

答案 0 :(得分:1)

我认为您不能仅通过调用某个函数来计算不同时期的异常,您需要分几个步骤进行。例如,如果在向量datevec中具有所有日期,而在var中具有数据,则应该能够做到:

a)每月支付:

for mon in range(1,13):
    kkmon = [ii for ii,val in enumerate(datevec) if val.month == mon]
    monmean = var[kkmon,:,:].mean(axis=0)

b)表示季节性:

seasons = {'DJF':[12,1,2],'MAM':[3,4,5],'JJA':[6,7,8],'SON':[9,10,11]}
for seaskey in seasons.keys():
    kkseas = [ii for ii,val in enumerate(datevec) if val.month in seasons[seaskey]]
    seasmean = var[kkseas,:,:].mean(axis=0)

这只是一个示例,您可以如何计算不同月份和季节的总体均值。您必须根据所拥有的数据和分辨率来计算异常。

我还建议考虑使用cdo(气候数据运算符)的可能性,因为大多数平均方法都内置在其中,并且它是用C或C ++编写的,因此与Python相比,它的工作速度要快得多。当然,您可以结合使用cdo和Python来完成任务-使用第一种方法来查找平均值,然后使用第二种方法来计算和绘制异常。

答案 1 :(得分:1)

我知道您正在寻找python的答案,但这是CDO(气候数据运算符)的基础,它使您可以从终端窗口中的一个或两个命令中进行此类计算。

例如,要获取Era Interim数据的年度平均值,您可以

cdo yearmean interim_t2m_19792017.nc erai_yearmean.nc

然后要计算年度异常,需要进行长期平均并减去

cdo timmean interim_t2m_19792017.nc erai_timemean.nc
cdo sub erai_yearmean.nc erai_timemean.nc yearanom.nc

您可以使用“管道”将上述所有3条命令组合在一起,但是我将它们分开放置在这里,因为这样可以更轻松地了解发生了什么。

您可以通过以下方式获取平均每月季节周期:

cdo ymonmean interim_t2m_19792017.nc erai_ymonmean.nc

这将为您提供一个文件,其中包含所有一月,二月等(12个时间片)的平均值。然后您可以计算每月异常,每个异常都与自己的每月平均值有关

cdo monmean interim_t2m_19792017.nc erai_monmean.nc
cdo sub erai_monmean.nc erai_ymonmean.nc erai_monanom.nc

还有一些用于季节性平均值的功能。

有关更多详细信息,请参见在线文档:https://code.mpimet.mpg.de/projects/cdo/

最后,msi_gerva在注释中是正确的,在该问题中尚不清楚异常是什么,因为您还可以计算与年度平均值或长期平均值有关的每月异常。此外,您要求每年出现异常,并说您只知道如何执行一年,但是我认为这没有多大意义,因为异常为零。更准确地阐明问题可能会有所帮助。

答案 2 :(得分:1)

在Linux和macOS上,可以使用nctoolkit(https://nctoolkit.readthedocs.io/en/latest/)完成此操作。如果您希望每年出现异常,可以执行以下操作:

import nctoolkit as nc
data = nc.open_data("./interim_t2m_19792017.nc")
data.annual_anomaly(baseline = [1997, 2017])

以及每月异常:

import nctoolkit as nc
data = nc.open_data("./interim_t2m_19792017.nc")
data.monthly_anomaly(baseline = [1997, 2017])

该软件包没有季节性异常,但是我将在以后的版本中添加。在后台,nctoolkit使用CDO,因此系统命令将类似于Adrian Tompkins提到的那些命令。