分水制度的情境分析¶
本笔记本分析三次不同实验的结果,分别是在不同的时间开始强制执行统一调度:
- 1998年
- 1987年
- 2020年(从不强制)
In [1]:
Copied!
%load_ext autoreload
%autoreload 2
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
from pathlib import Path
import pandas as pd
import numpy as np
from hydra import compose, initialize
import os
# 加载项目层面的配置
with initialize(version_base=None, config_path="../../config"):
cfg = compose(config_name="config")
os.chdir(cfg.root)
%load_ext autoreload
%autoreload 2
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
from pathlib import Path
import pandas as pd
import numpy as np
from hydra import compose, initialize
import os
# 加载项目层面的配置
with initialize(version_base=None, config_path="../../config"):
cfg = compose(config_name="config")
os.chdir(cfg.root)
在这次试验中,我们使用了三种情景:
- 基准情景(历史情景):在1998年,强制执行统一调度
- 1987年情景:在1987年配额制度颁布之初,就强制执行
- 2020年情景:截止研究时期结束,都不强制执行统一调度
In [2]:
Copied!
from src.ci import ExpAnalyzer
multirun = ExpAnalyzer("out/2024-06-07/20-50-35")
multirun.overrides
multirun.diff_runs
from src.ci import ExpAnalyzer
multirun = ExpAnalyzer("out/2024-06-07/20-50-35")
multirun.overrides
multirun.diff_runs
Out[2]:
{'farmer.forced_since': ['1987', '1998', '2020']}
Out[2]:
| farmer.forced_since | |
|---|---|
| 0 | 1998 |
| 1 | 2020 |
| 2 | 1987 |
将数据在省级尺度上进行聚合,可以分析不同时间执行统一调度,会对超采水资源带来怎样的影响。
In [3]:
Copied!
from src.ci import ResultAnalyzer
datasets = []
for subdir in multirun.subdir:
res = ResultAnalyzer(subdir)
data = res.get_data(level="province", water_unit="m3")
data["forced_since"] = res.select("farmer.forced_since")
datasets.append(data)
df = pd.concat(datasets)
from src.ci import ResultAnalyzer
datasets = []
for subdir in multirun.subdir:
res = ResultAnalyzer(subdir)
data = res.get_data(level="province", water_unit="m3")
data["forced_since"] = res.select("farmer.forced_since")
datasets.append(data)
df = pd.concat(datasets)
通过最基本的折线图,绘制地表水资源开采量随时间的变化曲线,可以反应不同的政策情景下的引黄用水情况:
- 如果1987年就开始,那么超配额的情况会在1987年之后就得到一定控制;
- 但是历史是在1998年开始,由于忽然开始强制配额制度,超配额的情况会存在;
- 如果一直没有强制执行统一调度,那么超配额的情况会持续存在,且略多于1998年开始的情况;
In [4]:
Copied!
%matplotlib inline
import seaborn as sns
ax = sns.lineplot(
df,
x="Time",
y="surface",
hue="forced_since",
)
sns.despine(ax=ax, offset=10, trim=True)
%matplotlib inline
import seaborn as sns
ax = sns.lineplot(
df,
x="Time",
y="surface",
hue="forced_since",
)
sns.despine(ax=ax, offset=10, trim=True)
为了细化这个分析,我们可以对比两个时间段的三种情景:
- 在1987年至1998年之间
- 在1987年至2010年之间
In [5]:
Copied!
from typing import Tuple
from matplotlib import pyplot as plt
from matplotlib.ticker import ScalarFormatter
formatter = ScalarFormatter() # 设置偏移为 1e9
formatter.set_scientific(True) # 明确开启科学记数法
formatter.set_powerlimits((0, 0)) # 应用于所有数值
start = 1988
end = 1998
def select_data(time: Tuple[int, int], cols=None) -> pd.DataFrame:
if cols is None:
cols = df["forced_since"].unique()
mask1 = df["forced_since"].isin(cols)
mask2 = df["Time"] <= time[-1]
mask3 = df["Time"] >= time[0]
return df.loc[mask1 & mask2 & mask3].copy()
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6, 2), tight_layout=True)
sns.violinplot(
data=select_data((1987, 2008), [1998, 2020]),
y="crop",
x="outdo",
hue="forced_since",
ax=ax2,
)
sns.violinplot(
data=select_data((1987, 1998), [1998, 2020]),
y="crop",
x="outdo",
hue="forced_since",
ax=ax1,
)
for ax in (ax1, ax2):
sns.despine(ax=ax, offset=5, trim=True)
ax.xaxis.set_major_formatter(formatter)
ax1.set_xlabel("1987-1998")
ax2.set_xlabel("1987-2008")
# fig.title('over withdraw')
ax2.set_ylabel("")
ax2.set_yticklabels("")
plt.show();
from typing import Tuple
from matplotlib import pyplot as plt
from matplotlib.ticker import ScalarFormatter
formatter = ScalarFormatter() # 设置偏移为 1e9
formatter.set_scientific(True) # 明确开启科学记数法
formatter.set_powerlimits((0, 0)) # 应用于所有数值
start = 1988
end = 1998
def select_data(time: Tuple[int, int], cols=None) -> pd.DataFrame:
if cols is None:
cols = df["forced_since"].unique()
mask1 = df["forced_since"].isin(cols)
mask2 = df["Time"] <= time[-1]
mask3 = df["Time"] >= time[0]
return df.loc[mask1 & mask2 & mask3].copy()
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6, 2), tight_layout=True)
sns.violinplot(
data=select_data((1987, 2008), [1998, 2020]),
y="crop",
x="outdo",
hue="forced_since",
ax=ax2,
)
sns.violinplot(
data=select_data((1987, 1998), [1998, 2020]),
y="crop",
x="outdo",
hue="forced_since",
ax=ax1,
)
for ax in (ax1, ax2):
sns.despine(ax=ax, offset=5, trim=True)
ax.xaxis.set_major_formatter(formatter)
ax1.set_xlabel("1987-1998")
ax2.set_xlabel("1987-2008")
# fig.title('over withdraw')
ax2.set_ylabel("")
ax2.set_yticklabels("")
plt.show();
由上图可以看出来,平均每年因种植小麦和水稻而超配额开采的黄河地表水资源更多
In [6]:
Copied!
start = 1987
end = 2010
scenario = 1998
data = select_data((start, end), cols=[1998, 2020])
agg = data.groupby(["province", "forced_since"])["outdo"].sum().reset_index()
sns.barplot(
agg,
x="province",
y="outdo",
hue="forced_since",
)
# print()
start = 1987
end = 2010
scenario = 1998
data = select_data((start, end), cols=[1998, 2020])
agg = data.groupby(["province", "forced_since"])["outdo"].sum().reset_index()
sns.barplot(
agg,
x="province",
y="outdo",
hue="forced_since",
)
# print()
黄河水资源分配制度的成功与失败
决策没有效应,农民的最优决策就是继续多用地表的灌溉水
In [7]:
Copied!
start = 1987
end = 2010
data = select_data((start, end))
agg = data.groupby(["province", "forced_since"])["surface"].sum().reset_index()
pivot = agg.pivot_table(
index="province", columns="forced_since", aggfunc="sum", values="surface"
)
data = pd.DataFrame(
{
"Scenario 1987": pivot[1987] - pivot[1998],
"Scenario 2020": pivot[2020] - pivot[1998],
}
)
melted_df = data.reset_index().melt(
id_vars=["province"], var_name="Scenario", value_name="Volume"
)
melted_df.head()
start = 1987
end = 2010
data = select_data((start, end))
agg = data.groupby(["province", "forced_since"])["surface"].sum().reset_index()
pivot = agg.pivot_table(
index="province", columns="forced_since", aggfunc="sum", values="surface"
)
data = pd.DataFrame(
{
"Scenario 1987": pivot[1987] - pivot[1998],
"Scenario 2020": pivot[2020] - pivot[1998],
}
)
melted_df = data.reset_index().melt(
id_vars=["province"], var_name="Scenario", value_name="Volume"
)
melted_df.head()
Out[7]:
| province | Scenario | Volume | |
|---|---|---|---|
| 0 | Gansu | Scenario 1987 | -6.687529e+09 |
| 1 | Henan | Scenario 1987 | -5.537660e+09 |
| 2 | Neimeng | Scenario 1987 | -1.024857e+10 |
| 3 | Ningxia | Scenario 1987 | -6.401384e+09 |
| 4 | Qinghai | Scenario 1987 | -8.244350e+08 |
In [31]:
Copied!
data.sum()
fig, ax = plt.subplots(figsize=(3, 2))
ax = sns.barplot(data.sum(), ax=ax)
ax.set_ylabel("Diff. WU from Yellow River")
ax.axhline(0, ls=":", color="red")
sns.despine(ax=ax, offset=5, trim=True)
plt.show();
data.sum()
fig, ax = plt.subplots(figsize=(3, 2))
ax = sns.barplot(data.sum(), ax=ax)
ax.set_ylabel("Diff. WU from Yellow River")
ax.axhline(0, ls=":", color="red")
sns.despine(ax=ax, offset=5, trim=True)
plt.show();
上面的图说明:
- 当一直不实用统一调度时,超配额的情况会持续存在,平均每年可能比历史情景多采 20.3 亿立方米的黄河水
- 如果尽早实施统一调度,相比于历史情景更能每年少采超20亿立方米的水,节约的水资源潜力更大
统一调度的优势¶
统一调度最大的优势,是把黄河水资源的分配权从地方政府转移到中央政府,这样可以更好地保护黄河水资源,避免超采的情况发生。
但在执行层面来说,这种总量控制形成的倒推机制,使得用水效率增加:
后续研究:
统一调度如何能够在释放粮食生产潜力的同时节约用水?