Рассчитать годовые аномалии за несколько лет в файлах netcdf в python - PullRequest
0 голосов
/ 23 сентября 2018

Мне нужно рассчитать месячные, сезонные и годовые аномалии температуры воздуха для ежемесячных файлов netcdf за 44 года с некоторой функцией, которая позволяет автоматически получать аномалии за период по месяцам, сезонам и годам и сохранять результаты в папке,Я только знаю, как сделать это в течение одного года, а не в течение нескольких лет с функцией.

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)

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Я знаю, что вы ищете ответ на языке Python, но это хлеб с маслом CDO (операторы климатических данных), который позволяет вам выполнять подобные вычисления в одной или двух командах из окна терминала.

Например, чтобы получить среднегодовые значения ваших промежуточных данных Era, вы можете сделать

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 команды, используя "piping", но я здесь их отдельно, так как легче увидеть, что происходит.

Вы можете получить среднемесячный сезонный цикл с помощью:

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 верна в комментарии, в вопросе о том, какие аномалии существуют, не ясно, как вы могли бытакже рассчитать месячные аномалии по отношению к среднегодовому или долгосрочному значению.Более того, вы просите о ежегодных аномалиях и говорите, что знаете, как это сделать только в течение одного года, но я не думаю, что это имеет смысл, поскольку аномалии будут равны нулю.Может быть полезно уточнить вопрос более точно.

0 голосов
/ 23 сентября 2018

Я думаю, что вы не можете рассчитать аномалии для разных периодов с помощью всего одного вызова какой-либо функции, вам нужно сделать это в несколько шагов.Например, если у вас есть все даты в векторе 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 (Climate Data Operators), так как большинство методов усреднения встроены в него и так какнаписано на C или C ++, работает намного быстрее по сравнению с Python.Конечно, вы можете комбинировать cdo и Python для своих задач - используйте первое, чтобы найти средства, а второе, чтобы потом рассчитать и построить аномалии.

...