目标:用python生成一组具有上下限的对数正态分布随机数。
思路:利用python的scipy.stats生成截断正态分布,再将正态分布转化为对数正态分布。
要求:生成的目标对数正态分布随机数要介于区间[log_lower,log_upper]内,这里设定该区间为[5, 10],并绘制正态分布与对数正态分布随机数的直方图。
源代码:
import numpy as np
from pylab import *
from scipy import stats
import matplotlib
import matplotlib.pyplot as plt
# 设置matplotlib正常显示中文和负号
matplotlib.rcParams['font.sans-serif'] = ['SimHei'] # 用黑体显示中文
matplotlib.rcParams['axes.unicode_minus'] = False # 正常显示负号
# region 【功能函数】生成截断对数正态分布,要求对数正态在[log_lower,log_upper]
def get_trunc_lognorm(mu, sigma, log_lower, log_upper=np.inf, data_num=10000):
norm_lower = np.log(log_lower)
norm_upper = np.log(log_upper)
X = stats.truncnorm((norm_lower - mu) / sigma, (norm_upper - mu) / sigma, loc=mu, scale=sigma)
norm_data = X.rvs(data_num)
log_data = np.exp(norm_data)
return norm_data, log_data
# endregion
mu, sigma = 0, 1
norm_data, log_data = get_trunc_lognorm(mu, sigma, 5, 10)
figure(4)
subplot(2, 1, 1)
plt.hist(norm_data, normed=1, bins=30)
plt.xticks(np.arange(mu - 5 * sigma, mu + 5 * sigma, 0.5))
plt.title("中间过程的截断正态分布")
subplot(2, 1, 2)
plt.hist(log_data, normed=1, bins=30)
plt.xticks(np.arange(0, 50, 5))
# plt.xlim(0,50)
plt.title("所求的截断对数正态分布")
plt.show()
执行结果: