You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python生成与自定义分布数据集同分布的随机数值生成器?

自定义分布随机数生成的Python实现方案

完全可以通过Python的开源统计/数值库实现你的需求,以下是几种实用且贴合你需求的方案:


1. 基于核密度估计(KDE)的采样(匹配你的KDE图需求)

使用scipy.stats.gaussian_kde拟合原数据的核密度分布,生成的样本会和你图中的KDE曲线分布高度一致,同时可以限制采样结果在原数据的最小值和最大值范围内。

import numpy as np
from scipy.stats import gaussian_kde

def custom_dist_generator(data):
    # 拟合原数据的KDE模型
    kde = gaussian_kde(data)
    data_min, data_max = data.min(), data.max()
    
    def generate():
        while True:
            # 生成样本并过滤超出值域的部分
            sample = kde.resample(1)[0][0]
            if data_min <= sample <= data_max:
                yield sample
    return generate

# 使用示例
original_data = np.array([1.2, 3.5, 2.1, 4.8, 2.9, ...])  # 替换为你的原始数据
gen = custom_dist_generator(original_data)
print(next(gen))  # 生成一个符合分布的随机数

2. 基于经验分布的采样(简单直接)

如果不需要严格拟合KDE,而是完全基于原数据的经验分布特征,可以通过分位数插值生成连续的随机样本,同样保证值域与原数据一致。

import numpy as np

def empirical_dist_generator(data):
    data_sorted = np.sort(data)
    data_min, data_max = data_sorted[0], data_sorted[-1]
    n = len(data_sorted)
    
    def generate():
        while True:
            # 生成0-1之间的均匀随机数,映射到经验分布的分位数
            u = np.random.uniform(0, 1)
            idx = u * n
            lower_idx = int(np.floor(idx))
            upper_idx = min(int(np.ceil(idx)), n-1)
            
            # 线性插值得到连续浮点样本
            if lower_idx == upper_idx:
                sample = data_sorted[lower_idx]
            else:
                t = idx - lower_idx
                sample = (1 - t) * data_sorted[lower_idx] + t * data_sorted[upper_idx]
            
            # 确保样本在值域范围内
            yield np.clip(sample, data_min, data_max)
    return generate

3. 自定义连续分布类(灵活扩展)

通过继承scipy.stats.rv_continuous,可以将原数据的经验分布封装为标准的统计分布类,支持采样、CDF、PPF等多种操作,同时严格限制值域。

from scipy.stats import rv_continuous
import numpy as np

class CustomEmpiricalDistribution(rv_continuous):
    def __init__(self, data, *args, **kwargs):
        super().__init__(a=data.min(), b=data.max(), *args, **kwargs)
        self.data_sorted = np.sort(data)
        self.n = len(self.data_sorted)
    
    def _cdf(self, x):
        # 实现经验累积分布函数
        if x < self.a:
            return 0.0
        if x >= self.b:
            return 1.0
        return np.searchsorted(self.data_sorted, x, side='right') / self.n
    
    def _ppf(self, q):
        # 实现分位数函数,用于采样
        if q <= 0:
            return self.a
        if q >= 1:
            return self.b
        idx = q * self.n
        lower_idx = int(np.floor(idx))
        upper_idx = min(int(np.ceil(idx)), self.n-1)
        if lower_idx == upper_idx:
            return self.data_sorted[lower_idx]
        t = idx - lower_idx
        return (1 - t) * self.data_sorted[lower_idx] + t * self.data_sorted[upper_idx]

def custom_dist_generator(data):
    dist = CustomEmpiricalDistribution(data)
    def generate():
        while True:
            yield dist.rvs()
    return generate

内容的提问来源于stack exchange,提问作者Fabre Lambeau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 05:31:20