如何按指定连续概率密度函数生成随机变量?代码问题求助
解决方法
一、前两个缩放正态分布的正确生成方式
缩放正态分布本质是正态分布的线性变换,无需自定义PDF,直接用numpy或scipy的内置函数即可实现:
分布1:µ=260/3,σ=100/3,缩放因子1.53666351546
import numpy as np # 参数定义 mu1 = 260 / 3 sigma1 = 100 / 3 scale_factor1 = 1.53666351546 # 生成单个随机变量 x1 = scale_factor1 * np.random.normal(mu1, sigma1) # 生成1000个批量样本 x1_samples = scale_factor1 * np.random.normal(mu1, sigma1, size=1000)
分布2:µ=854/9,σ=100/3,缩放因子1.78979465778
mu2 = 854 / 9 sigma2 = 100 / 3 scale_factor2 = 1.78979465778 # 生成单个随机变量 x2 = scale_factor2 * np.random.normal(mu2, sigma2) # 生成1000个批量样本 x2_samples = scale_factor2 * np.random.normal(mu2, sigma2, size=1000)
注:此处的“缩放”指对正态分布随机变量的线性缩放,若你是指对PDF进行归一化缩放,需重新计算归一化常数,但通常“缩放正态分布”默认指随机变量的线性变换。
二、11个正态分布+2个半正态分布的和
生成逻辑:分别生成每个分布的随机变量后直接相加即可。半正态分布可通过scipy.stats.halfnorm实现,或直接取正态分布的绝对值(等价于半正态)。
示例代码
请替换示例中的参数为你的实际参数:
import numpy as np from scipy import stats # 11个正态分布的参数列表(每个元素为(均值, 标准差)) norm_params = [ (mu_1, sigma_1), (mu_2, sigma_2), ..., (mu_11, sigma_11) ] # 2个半正态分布的尺度参数列表 halfnorm_params = [sigma_a, sigma_b] def generate_mixed_sum(): # 计算11个正态变量的和 norm_sum = sum(np.random.normal(mu, sigma) for mu, sigma in norm_params) # 计算2个半正态变量的和 halfnorm_sum = sum(stats.halfnorm.rvs(scale=sigma) for sigma in halfnorm_params) # 返回总和 return norm_sum + halfnorm_sum # 生成单个样本 mixed_sample = generate_mixed_sum() # 生成1000个批量样本 mixed_samples = [generate_mixed_sum() for _ in range(1000)]
三、现有代码的问题与警告解决
你当前的代码存在两个核心问题:
- 自定义的PDF是五次指数型分布,和你需求中的“缩放正态分布”完全不符,属于需求误解;
- 混用
Decimal与numpy/scipy导致类型不兼容——scipy的rv_continuous依赖numpy数组运算,而Decimal是Python原生高精度类型,两者无法高效兼容,触发了数值运算警告。
若确实需要自定义非正态分布(非需求内场景)
修正类型兼容问题后的代码示例:
from scipy import stats import numpy as np Q = 0.0460999054638 / np.sqrt(2 * np.pi) class Distribution_B(stats.rv_continuous): def _pdf(self, x): return Q * np.exp(-((260 - 3*x)**5) / 20000) # 定义分布区间 distribution = Distribution_B(a=0, b=100) # 生成样本(仍可能有数值警告,需确认PDF的归一化合理性) sample = distribution.rvs()
再次强调:该自定义分布与你需求中的“缩放正态分布”无关,建议回到前两种方法实现原始需求。
内容的提问来源于stack exchange,提问作者Qaos
相关产品推荐
相关产品推荐

