You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
5.2 KiB
Python
126 lines
5.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Created on Thu Jun 14 16:32:01 2018
|
|
|
|
@author: z5025317
|
|
"""
|
|
|
|
import matplotlib.pyplot as plt
|
|
from datetime import datetime, timedelta
|
|
import numpy as np
|
|
import pandas as pd
|
|
|
|
|
|
|
|
def compare_images(im1, im2):
|
|
"""plots 2 images next to each other, sharing the axis"""
|
|
plt.figure()
|
|
ax1 = plt.subplot(121)
|
|
plt.imshow(im1, cmap='gray')
|
|
ax2 = plt.subplot(122, sharex=ax1, sharey=ax1)
|
|
plt.imshow(im2, cmap='gray')
|
|
plt.show()
|
|
|
|
def reject_outliers(data, m=2):
|
|
"rejects outliers in a numpy array"
|
|
return data[abs(data - np.mean(data)) < m * np.std(data)]
|
|
|
|
def duplicates_dict(lst):
|
|
"return duplicates and indices"
|
|
# nested function
|
|
def duplicates(lst, item):
|
|
return [i for i, x in enumerate(lst) if x == item]
|
|
|
|
return dict((x, duplicates(lst, x)) for x in set(lst) if lst.count(x) > 1)
|
|
|
|
def datenum2datetime(datenum):
|
|
"convert datenum to datetime"
|
|
#takes in datenum and outputs python datetime
|
|
time = [datetime.fromordinal(int(dn)) + timedelta(days=float(dn)%1) - timedelta(days = 366) for dn in datenum]
|
|
return time
|
|
|
|
|
|
|
|
|
|
def select_min_med_max_dif_model(NARCLIM_df):
|
|
#Select the 3 most representative models (min med and max difference betwen far future and present)
|
|
Fdf_1900_2080_sorted = NARCLIM_df.reindex_axis(sorted(NARCLIM_df.columns), axis=1)
|
|
Fdf_1900_2080_sorted_means = pd.DataFrame(Fdf_1900_2080_sorted.mean())
|
|
df = Fdf_1900_2080_sorted_means
|
|
#add a simple increasing integer index
|
|
df = df.reset_index()
|
|
df= df[df.index % 3 != 1]
|
|
df['C'] = df[0].diff()
|
|
df = df.reset_index()
|
|
df= df[df.index % 2 != 0]
|
|
#get max difference model (difference between far future and prsent day)
|
|
a = df[df.index == df['C'].argmax(skipna=True)]
|
|
Max_dif_mod_name = a.iloc[0]['index']
|
|
#get min difference model
|
|
a = df[df.index == df['C'].argmin(skipna=True)]
|
|
Min_dif_mod_name = a.iloc[0]['index']
|
|
#get the model which difference is closest to the median difference
|
|
df['D'] = abs(df['C']- df['C'].median())
|
|
a = df[df.index == df['D'].argmin(skipna=True)]
|
|
Med_dif_mod_name = a.iloc[0]['index']
|
|
#data frame with min med and max difference model
|
|
df2 = NARCLIM_df.filter(regex= Min_dif_mod_name[:-5] + '|' + Med_dif_mod_name[:-5] + '|' + Max_dif_mod_name[:-5] )
|
|
dfall = df2.reindex_axis(sorted(df2.columns), axis=1)
|
|
#data frame with individual models
|
|
dfmin = NARCLIM_df.filter(regex= Min_dif_mod_name[:-5])
|
|
dfmax = NARCLIM_df.filter(regex= Max_dif_mod_name[:-5])
|
|
dfmed = NARCLIM_df.filter(regex= Max_dif_mod_name[:-5])
|
|
return dfall , dfmin, dfmed, dfmax, Min_dif_mod_name,Med_dif_mod_name, Max_dif_mod_name
|
|
|
|
|
|
def calculate_deltas_NF_FF2(Annual_df, Seasonal_df):
|
|
"""calculates the "deltas" between nearfuture and present day for annual or seasonal climate data in pandas TS format"""
|
|
|
|
times = ['annual', 'DJF', 'MAM', 'JJA','SON']
|
|
delta_all_df = pd.DataFrame()
|
|
for temp in times:
|
|
if temp == 'annual':
|
|
Mean_df = Annual_df.mean()
|
|
Column_names = ['near', 'far']
|
|
if temp == 'DJF':
|
|
Mean_df = Seasonal_df[Seasonal_df.index.quarter==1].mean()
|
|
Column_names = ['DJF_near', 'DJF_far']
|
|
if temp == 'MAM':
|
|
Mean_df = Seasonal_df[Seasonal_df.index.quarter==2].mean()
|
|
Column_names = ['MAM_near', 'MAM_far']
|
|
if temp == 'JJA':
|
|
Mean_df = Seasonal_df[Seasonal_df.index.quarter==3].mean()
|
|
Column_names = ['JJA_near', 'JJA_far']
|
|
if temp == 'SON':
|
|
Mean_df = Seasonal_df[Seasonal_df.index.quarter==4].mean()
|
|
Column_names = ['SON_near', 'SON_far']
|
|
models = list(Seasonal_df.mean().index)
|
|
newmodel = []
|
|
type(newmodel)
|
|
for each in models:
|
|
newmodel.append(each[:-5])
|
|
unique_models = set(newmodel)
|
|
# calculate diff for each unique model
|
|
delta_NF_ensemble = []
|
|
delta_FF_ensemble = []
|
|
for unique_model in unique_models:
|
|
dfdiff = Mean_df.filter(regex= unique_model)
|
|
type(dfdiff)
|
|
delta_NF = dfdiff[1] - dfdiff[0]
|
|
delta_NF_ensemble.append(delta_NF)
|
|
delta_FF = dfdiff[2] - dfdiff[1]
|
|
delta_FF_ensemble.append(delta_FF)
|
|
|
|
delta_df1=pd.DataFrame(delta_NF_ensemble, index=unique_models)
|
|
delta_df2=pd.DataFrame(delta_FF_ensemble, index=unique_models)
|
|
delta_df= pd.concat([delta_df1, delta_df2], axis=1)
|
|
|
|
#rename columns
|
|
delta_df.columns = Column_names
|
|
#add a row with medians and 10 and 90th percentiles
|
|
delta_df.loc['10th'] = pd.Series({Column_names[0]:np.percentile(delta_df[Column_names[0]], 10), Column_names[1]:np.percentile(delta_df[Column_names[1]], 10)})
|
|
delta_df.loc['median'] = pd.Series({Column_names[0]:np.percentile(delta_df[Column_names[0]], 50), Column_names[1]:np.percentile(delta_df[Column_names[1]], 50)})
|
|
delta_df.loc['90th'] = pd.Series({Column_names[0]:np.percentile(delta_df[Column_names[0]], 90), Column_names[1]:np.percentile(delta_df[Column_names[1]], 90)})
|
|
#append df to overall df
|
|
delta_all_df = pd.concat([delta_all_df, delta_df], axis=1)
|
|
return delta_all_df |