对数正态分布累积重量分数计算代码结果与预期不符,求协助
对数正态分布累积重量分数计算代码排查
我写了一段生成累积重量分数的代码,但计算结果和预期不符(预期结果见附图),麻烦帮忙排查问题。输入参数是D50=1、几何标准差(Geometric Mean Deviation)=0.4,代码如下:
import numpy as np from scipy.stats import lognorm import pandas as pd # 原代码遗漏导入,补充后避免运行报错 def lognormal_cdf(x, D50, gsd): # 计算对数正态分布的mu和sigma参数 sigma = np.sqrt(np.log(1 + (gsd ** 2))) mu = np.log(D50) - 0.5 * sigma ** 2 # 计算并返回CDF值 cdf = lognorm.cdf(x, sigma, scale=np.exp(mu)) return cdf D50 = 1.0 # 中位值(D50) gsd = 0.4 # 几何标准差 # 示例用法 lower_limit = 0.0 upper_limit = 10.0 intervals = 10 # 需要计算CDF的区间数量 diff = (upper_limit - lower_limit) / intervals lower_limits = np.linspace(lower_limit, upper_limit - diff, intervals) upper_limits = np.linspace(lower_limit + diff, upper_limit, intervals) # 计算CDF cdf_value = lognormal_cdf(upper_limits, D50, gsd) # 输出结果 df = pd.DataFrame([lower_limits, upper_limits, cdf_value]).T df.columns = ['lower limits', 'upper limits', 'cumulative mass fraction'] print(df)
当前输出见附图,预期结果见附图。我试过用lognorm.cdf(x, sigma, scale=np.exp(mu))以及网上找的变换方法,问题还是没解决。
问题排查与修正
1. 几何标准差(GSD)的参数转换错误
对数正态分布中,几何标准差GSD和分布参数σ的正确关系是σ = np.log(gsd),你用的sigma = np.sqrt(np.log(1 + (gsd ** 2)))是算术标准差转对数正态σ的公式,完全不适用几何标准差的场景。
2. 位置参数mu的计算错误
D50是对数正态分布的中位数,对数后的中位数就是μ(因为对数正态分布的中位数对应exp(mu)),所以正确计算应为mu = np.log(D50),不需要减去0.5 * sigma ** 2——这个修正仅针对给定算术均值的情况,和D50中位数无关。
修正后的代码
import numpy as np from scipy.stats import lognorm import pandas as pd def lognormal_cdf(x, D50, gsd): # 修正后的参数计算逻辑 sigma = np.log(gsd) mu = np.log(D50) # scipy lognorm参数对应关系:s=sigma,scale=exp(mu) cdf = lognorm.cdf(x, s=sigma, scale=np.exp(mu)) return cdf D50 = 1.0 gsd = 0.4 lower_limit = 0.0 upper_limit = 10.0 intervals = 10 diff = (upper_limit - lower_limit) / intervals lower_limits = np.linspace(lower_limit, upper_limit - diff, intervals) upper_limits = np.linspace(lower_limit + diff, upper_limit, intervals) cdf_value = lognormal_cdf(upper_limits, D50, gsd) df = pd.DataFrame([lower_limits, upper_limits, cdf_value]).T df.columns = ['lower limits', 'upper limits', 'cumulative mass fraction'] print(df)
验证逻辑
对数正态分布CDF的定义是:若变量X~Lognormal(μ,σ),则其CDF为Φ((lnX - μ)/σ)(Φ为标准正态分布CDF)。scipy的lognorm.cdf参数中,s对应σ,scale对应exp(μ),修正后的参数完全匹配这个定义。
内容的提问来源于stack exchange,提问作者cheng_grd
相关产品推荐
相关产品推荐

