模拟管网与真实管网的区别在于模式太过单一,本文旨在生成随温度,工作休息日变化的水力需求。
wntr包中是使用add_pattern来添加用水模式的,我们需要通过传入一个列表来确定需水量的乘子。假定我们的传感器是15min传入一次数据,一天24小时我们一共需要24*60/15=96个数字来指定乘子。根据城市用水的大致趋势,即凌晨用水非常少(波动不大),早晚高峰用水明显(两个峰值)。
1.我们首先创建一个用水量乘子列表作为我们的日平均波动。
import numpy as np
#用水基本模式(每天不同时间的乘子模式)
a = [0.9,0.8,0.7,0.7,
0.7,0.6,0.6,0.6,
0.5,0.5,0.5,0.5,
0.5,0.5,0.5,0.5,
0.5,0.6,0.6,0.6,
0.6,0.7,0.7,0.7,
0.8,0.9,1.0,1.1,
1.2,1.3,1.4,1.5,
1.5,1.6,1.5,1.5,
1.5,1.4,1.4,1.3,
1.3,1.2,1.3,1.2,
1.3,1.3,1.2,1.2,
1.3,1.3,1.2,1.2,
1.2,1.2,1.3,1.2,
1.2,1.1,1.1,1.0,
1.1,1.0,1.1,1.0,
1.0,1.1,1.2,1.2,
1.3,1.3,1.4,1.4,
1.4,1.5,1.5,1.6,
1.4,1.3,1.3,1.2,
1.2,1.1,1.0,1.0,
1.0,1.0,0.9,1.0,
1.1,1.0,1.1,1.0,
0.9,0.9,0.9,0.9]
pattern_init= np.array(a)
2.根据我们每天的温度添加一个温度的固定趋势,暂定为从15度开始,每升高/降低1摄氏度,乘子系数增加/降低0.01
#这里我们找到12个月的平均温度,也可以找365天的或者周温度,但是实在太麻烦了
temp = [8,11,16,21,24,27,32,31,26,20,15,10]
temp_init = np.array(temp)
temp_mul = (temp_init-15)*0.01
3.接着我们把用水量的背景泄漏考虑进去,乘子系数加0.2,假设每年的用水增长量为20%(0.2),每一周为0.004
#建立一个全为0的数组
data_pat = np.zeros(shape=(1,96))
for i in range(48):
np.random.seed(i)
ran = np.random.normal(loc=0, scale=0.01, size=(96,))
#进行乘子的计算
pattern_final = pattern_init+temp_mul[i//7]+ran+0.2+0.004*i
#转换成数组
data_ = np.array(pattern_final).reshape(1,96)
#竖直拼接
data_pat =np.vstack((data_pat,data_))
#删掉第一行,转换成DataFrame输出
data_pat = pd.DataFrame(data_pat).drop(0,axis=0)
data_pat.to_csv('patdata2.csv')
成功,每一行是周数,当然也可以换成每天的乘子数量。
下图代码为按照天数计算的乘子数,随机波动性强,用户之后训练算法:
import numpy as np
import pandas as pd
pattern_init = [0.9,0.8,0.7,0.7,
0.7,0.6,0.6,0.6,
0.5,0.5,0.5,0.5,
0.5,0.5,0.5,0.5,
0.5,0.6,0.6,0.6,
0.6,0.7,0.7,0.7,
0.8,0.9,1.0,1.1,
1.2,1.3,1.4,1.5,
1.5,1.6,1.5,1.5,
1.5,1.4,1.4,1.3,
1.3,1.2,1.3,1.2,
1.3,1.3,1.2,1.2,
1.3,1.3,1.2,1.2,
1.2,1.2,1.3,1.2,
1.2,1.1,1.1,1.0,
1.1,1.0,1.1,1.0,
1.0,1.1,1.2,1.2,
1.3,1.3,1.4,1.4,
1.4,1.5,1.5,1.6,
1.4,1.3,1.3,1.2,
1.2,1.1,1.0,1.0,
1.0,1.0,0.9,1.0,
1.1,1.0,1.1,1.0,
0.9,0.9,0.9,0.9]
a = np.array(pattern_init)
temp = [8,11,16,21,24,27,32,31,26,20,15,10]
temp_init = np.array(temp)
temp_mul = (temp_init-15)*0.01
#添加一个正态分布
#随时间逐渐偏大的偏移量 一年0.2 每周就是0.0006
#0.2的背景泄漏,所以总的时间乘子数应该如何算
data_pat = np.zeros(shape=(1,96))
for i in range(365):
np.random.seed(i)
ran = np.random.normal(loc=0, scale=0.01, size=(96,))
pattern_final = pattern_init+temp_mul[i//31]+ran+0.2+0.0006*i
data_ = np.array(pattern_final).reshape(1,96)
data_pat =np.vstack((data_pat,data_))
data_pat = pd.DataFrame(data_pat).drop(0,axis=0)
data_pat.to_csv('patdata3.csv')