эффективно использовать радужную оболочку для объединения радужной оболочки и анализа и агрегирования при выводе времени появления - PullRequest
0 голосов
/ 14 декабря 2018

Я использую python / iris для получения годовых экстремальных значений из ежедневных данных.Я использую aggregated_by ('season_year', iris.analysis.MIN), чтобы получить экстремальные значения, но мне также нужно знать, когда они появляются в каждом году.Я написал код ниже, но он действительно медленный, поэтому мне интересно, знает ли кто-нибудь, может быть, встроенный в ирис способ сделать это, или может ли другой способ придумать более эффективный способ?

Спасибо!

#--- get daily data
cma = iris.load_cube('daily_data.nc')

#--- get annual extremes
c_metric = cma.aggregated_by('season_year', iris.analysis.MIN)

#--- add date of when the extremes are occurring
extrdateli=[]

#loop over all years
for mij in range(c_metric.data.shape[0]):
    #
    #get extreme value
    m=c_metric.data[mij]
    #
    #get values for this year
    cma_thisseasyr = cma.extract(iris.Constraint(season_year=lambda season_year:season_year==c_metric.coord('season_year').points[mij]))
    #
    #get date in data cube for when this extreme occurs and print add as string to a list
    extradateli += [ str(c_metric.coord('season_year').points[mij])+':'+','.join([''.join(_) for _ in zip([str(_) for _ in cma_thisseasyr.coord('day').points[np.where(cma_thisseasyr.data==m)]], [str(_) for _ in cma_thisseasyr.coord('month').points[np.where(cma_thisseasyr.data==m)]], [str(_) for _ in cma_thisseasyr.coord('year').points[np.where(cma_thisseasyr.data==m)]])])]

#add this list to the metric cube as attribute
c_metric.attributes['date_of_extreme_value'] = ' '.join(extrdateli)

#--- save to file
iris.save('annual_min.nc')

1 Ответ

0 голосов
/ 14 декабря 2018

Я думаю, что в медленной части вы извлекаете значения для каждого сезона.Вы можете немного ускорить это, отказавшись от lambda, то есть:

iris.Constraint(season_year=c_metric.coord('season_year').points[mij])

Если это все еще слишком медленно, вы можете работать непосредственно с массивами numpy в вашем кубе.Нарезка пустых массивов намного быстрее, чем извлечение из кубов.Для простоты в примере ниже предполагается, что у вас есть временная координата.

import iris
import numpy as np
import iris.coord_categorisation as cat

#--- create a dummy data cube
ndays = 12 * 365 + 3  # 12 years of data
tcoord = iris.coords.DimCoord(range(ndays), units='days since 2001-02-01',
                              standard_name='time')

cma = iris.cube.Cube(np.random.normal(0, 1, ndays), long_name='blah')
cma.add_dim_coord(tcoord, 0)
cat.add_season_year(cma, 'time')

#--- get annual extremes
c_metric = cma.aggregated_by('season_year', iris.analysis.MIN)

#--- add date of when the extremes are occurring
extrdateli=[]

#loop over all years
for mij in range(c_metric.data.shape[0]):
    #
    #get extreme value
    m = c_metric.data[mij]
    #
    #get values for this year
    year_index = cma.coord('season_year').points == c_metric.coord('season_year').points[mij]
    temperatures_this_syear = cma.data[year_index]
    dates_this_syear = tcoord.units.num2date(tcoord.points[year_index])
    #
    #get date in data cube for when this extreme occurs and print add as string to a list
    extreme_dates = dates_this_syear[temperatures_this_syear==m]
    extrdateli += [ str(c_metric.coord('season_year').points[mij])+':'+','.join(str(date) for date in extreme_dates)]


#add this list to the metric cube as attribute
c_metric.attributes['date_of_extreme_value'] = ' '.join(extrdateli)
...