示例: Tumurbulag Soum 模拟计算 ============================== 这里以 Tumurbulag Soum 的计算为例,说明如何在 Jupyter 中进行模拟计算。 数据准备与计算 -------------- .. code:: python3 import pysd import numpy as np import pandas as pd import re from pathlib import Path import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') 定义三种情景模拟参量。 .. code:: python3 keys = ['Forage production','Carrying capacity','Livestock','Livestock output','Livestock output rate'] 定义函数,针对多情景模拟进行计算。 .. code:: python3 def calculate(project_path): historical_livestock = pd.read_excel( project_path / 'input_data.xlsx', 'historical_livestock').iloc[1][2:].values.astype('float') for scenario in [126,245,585]: fn = project_path / 'models' / f'{scenario}.py' strings = open(fn).read() modified_string = re.sub(r',\n lambda: (\d+)', r',\n lambda: '+str(int(historical_livestock[0])), strings) open(fn,'w',encoding='utf-8').write(modified_string) x = np.log(np.arange(1,historical_livestock.shape[0]+1)) BAUk,BAUb = np.polyfit(x,historical_livestock,1) x = np.arange(36) BAU_values = BAUk*np.log(x)+BAUb all_results = [] for scenario in [126,245,585]: model = pysd.load( project_path / 'models' / f'{scenario}.py' ) all_results.append(model.run()[keys]) for key in keys: all_results[0][key].iloc[7] = all_results[1].iloc[7][key] all_results[1][key].iloc[7] = all_results[1].iloc[7][key] all_results[2][key].iloc[7] = all_results[1].iloc[7][key] all_results[0]['Livestock'].iloc[7] = historical_livestock[-1] # 126 all_results[1]['Livestock'].iloc[7] = historical_livestock[-1] # 245 all_results[2]['Livestock'].iloc[7] = historical_livestock[-1] # 585 return all_results,BAU_values 2022-2050年畜牧业系统情景 ------------------------- .. code:: python3 project_path = Path('Tumurbulag') all_results, BAU_values = calculate(project_path) results = [i[7:] for i in all_results] 定义函数,对模拟数据进行制图。 .. code:: python3 def show_results(results): colors = ['blue','red','green'] plt.figure(figsize=(16,10)) plt.subplot(2,2,1) for i in range(3): plt.plot(np.arange(2022,2051),results[i]['Forage production'].values,colors[i]) plt.legend(['SSP126','SSP245','SSP585'],loc='upper right') plt.title('Scenarios of Forage production during 2022-2050 ') plt.subplot(2,2,2) for i in range(3): plt.plot(np.arange(2022,2051),results[i]['Carrying capacity'].values,colors[i]) plt.legend(['SSP126','SSP245','SSP585'],loc='upper right') plt.title('Scenarios of Carrying capacity during 2022-2050 ') plt.subplot(2,2,3) for i in range(3): plt.plot(np.arange(2022,2051),results[i]['Livestock'].values,colors[i]) plt.legend(['SSP126','SSP245','SSP585'],loc='upper right') plt.title('Scenarios of Livestok during 2022-2050 ') plt.subplot(2,2,4) for i in range(3): plt.plot(np.arange(2022,2051),results[i]['Livestock output'].values,colors[i]) plt.legend(['SSP126','SSP245','SSP585'],loc='upper right') plt.title('Scenarios of Livestock output during 2022-2050 ') show_results(results) .. image:: ./imgs_files/imgs_9_0_xac.png 定义函数计算调控参数: .. code:: python3 def scen(results): means = [] stds = [] MV = [] SV = [] for key in keys: mean_ = np.array([re[key].mean() for re in results]) MV.extend(mean_) std_ = np.array([re[key].std() for re in results]) SV.extend(std_) means.append((mean_==(mean_.max()))+(mean_==(mean_.min()))*-1) stds.append((std_==(std_.min()))+(std_==(std_.max()))*-1) MV.extend([np.nan]*3) SV.extend([np.nan]*3) index = pd.MultiIndex.from_product( [["Forage production/ton", "Carrying capacity/SU","Livestock/SU","Livestock output/SU","Livestock output rate/SU","Sustainability scores"], ["SSP126", "SSP245", "SSP585"]], names=["Variable", "Scenarios"] ) columns = ["MV", "SV", "MV'", "SV'", "TV_j"] MV_ = np.concatenate([np.array(means).flatten(),np.array(means).sum(axis=0)]) SV_ =np.concatenate([np.array(stds).flatten(),np.array(stds).sum(axis=0)]) TV = MV_+SV_ data = np.concatenate([[MV],[SV],[MV_],[SV_],[TV]]) Sus_df = pd.DataFrame(data.T, index=index, columns=columns) return Sus_df, means, stds 进行计算,查看结果: .. code:: python3 Sus_df,means, stds = scen(results) Sus_df 定义函数,计算调控结果: .. code:: python3 def show_text(): TV = np.array(means).sum(axis=0)+np.array(stds).sum(axis=0) if TV[1]>=2: SSP_index=1 else: SSP_index = np.argmax(TV) Best_Scenario = 'SSP'+str([126,245,585][SSP_index]) text = f"""Best Scenario is {Best_Scenario}. Over the next three decades, forage production, carrying capacity, livestock numbers and livestock output fluctuate and remain stable. Among the three scenarios (SSP126, SSP245 and SSP585),the {Best_Scenario} scenario for {project_path.name} in the lower reaches of the basin, was identified as the rational scenario for the highest productivity and stability. """ print(text) return SSP_index, Best_Scenario 运行上面函数: .. code:: python3 SSP_index, Best_Scenario = show_text() .. parsed-literal:: Best Scenario is SSP126. Over the next three decades, forage production, carrying capacity, livestock numbers and livestock output fluctuate and remain stable. Among the three scenarios (SSP126, SSP245 and SSP585),the SSP126 scenario for Tumurbulag in the lower reaches of the basin, was identified as the rational scenario for the highest productivity and stability. 历史期和预测期之间的库存率变化 ------------------------------ 定义函数,计算变化 : .. code:: python3 def change(): historical_data = pd.read_excel(project_path / 'input_data.xlsx','grassland_area').iloc()[SSP_index+1][2:9] grass_land_area = np.nanmean(historical_data.values) Carrying_capacity_Scenario = Sus_df['MV']['Carrying capacity/SU'][SSP_index] Forage_production_Scenario = Sus_df['MV']['Forage production/ton'][SSP_index] Livestock_Scenario = Sus_df['MV']['Livestock/SU'][SSP_index] Livestock_output_Scenario = Sus_df['MV']['Livestock output/SU'][SSP_index] Forage_production_before = all_results[SSP_index][:8]['Forage production'].mean() Carrying_capacity_before = all_results[SSP_index][:8]['Carrying capacity'].mean() Livestock_before = all_results[SSP_index][:8]['Livestock'].mean() Livestock_output_before = all_results[SSP_index][:8]['Livestock output'].mean() data = [[project_path.name, '2015-2022', '%d'%(Forage_production_before/grass_land_area*1000), '%d' %(Carrying_capacity_before), '%.2f'%(Carrying_capacity_before/grass_land_area), '%d'%(Livestock_before),'%.2f'%(Livestock_before/Carrying_capacity_before), '%d'%(Livestock_output_before)], ['', '2022-2050', '%d'%(Forage_production_Scenario/grass_land_area*1000), '%d' %(Carrying_capacity_Scenario), '%.2f'%(Carrying_capacity_Scenario/grass_land_area), '%d'%(Livestock_Scenario), '%.2f'%(Livestock_Scenario/Carrying_capacity_Scenario), '%d'%(Livestock_output_Scenario)] ] # Define indexes for multiple layers of columns columns = pd.MultiIndex.from_tuples([ ('Soums', ''), ('Period', ''), ('Grassland', 'Forage (kg/ha)'), ('Grassland', 'Carrying capacity (SU)'), ('Grassland', 'Carrying capacity (SU/ha)'), ('Livestock', 'Livestock (SU)'), ('Livestock', 'Stocking rate'), ('Livestock', 'Livestock output (SU)') ]) change_df = pd.DataFrame(data, columns=columns) num1 = (Forage_production_Scenario-Forage_production_before)*100/Forage_production_before num2 = Carrying_capacity_before/grass_land_area num3 = Carrying_capacity_Scenario/grass_land_area num4 = Livestock_before/Carrying_capacity_before num5 = Livestock_Scenario/Carrying_capacity_Scenario text = f'''The projected average forage yield in {project_path.name} is expected to {'increase' if num1 > 0 else'decrease'} by {'%.2f'%(abs(num1))}%, compared to the historical period. The carrying capacity is projected to {'decrease' if num2