如何让这个 python 代码运行得更快?

Posted

技术标签:

【中文标题】如何让这个 python 代码运行得更快?【英文标题】:How can I make this python code run faster? 【发布时间】:2021-11-03 01:16:06 【问题描述】:

我有两个问题:

1- 此代码执行时间过长。知道如何让它更快吗? 使用下面的代码,我想生成 100 个介于 700 和 1200 之间的随机离散值。

我选择了weibull分布,因为我想生成故障率数据,请看下面的直方图。

    import random
    nums = [] 
    alpha = 0.6
    beta = 0.4
        
    while len(nums) !=100: 
        temp = int(random.weibullvariate(alpha, beta))
        if 700 <= temp <1200:
            nums.append(temp)
            print(nums)
            
    # plotting a graph 
    #plt.hist(nums, bins = 200) 
    #plt.show()
    print(nums)

我想生成这样的直方图: Histogram

2- 我有这个函数用于离散威布尔分布

def DiscreteWeibull(q, b, x):
    return q**(x**b) - q**((x + 1)**b)

如何生成遵循此分布的随机值?

【问题讨论】:

什么是“离散”数? 您希望如何获得介于 700 和 1200 之间的值?威布尔函数是否曾经接近如此高的值?似乎生成超过 700 的值的概率接近于零。 对。当我在分配 temp 的行之后添加一个打印语句时,我看到的大多数数字都低于 10 - 所以我想获得超过 700 的数字需要很长时间。 @SamMatzko 三是离散和连续分布。使用上面的代码,我想生成随机离散值 @not_speshal 我不明白你的意思。我只想生成 700 到 1200 之间遵循离散威布尔分布的随机数 【参考方案1】:

由于具有形状参数 K 和尺度参数 lambda 的 Weibull 分布可以表征为 Uniform (0,1) dist 上的此函数。 U, 我们可以将分布“切割”到所需的最小值和最大值。我们通过反转等式,将 W 设置为 700 或 1200,并找到对应的 0 和 1 之间的值来做到这一点。这是一些示例代码。

def weibull_from_uniform(shape, scale, x):
    assert 0 <= x <= 1
    return scale * pow(-1 * math.log(x), 1.0 / shape)


scale_param = 0.6
shape_param = 0.4

min_value = 700.0
max_value = 1200.0

lower_bound = math.exp(-1 * pow(min_value / scale_param, shape_param))
upper_bound = math.exp(-1 * pow(max_value / scale_param, shape_param))

if lower_bound > upper_bound:
    lower_bound, upper_bound = upper_bound, lower_bound


nums = []

while len(nums) < 100:
    nums.append(weibull_from_uniform(shape_param, scale_param, random.uniform(lower_bound, upper_bound)))

print(nums)
plt.hist(nums, bins=8)
plt.show()

此代码给出的直方图与您提供的非常相似;该方法将提供与原始方法相同分布的值,只是速度更快。请注意,这种直接方法仅在我们的形状参数 K 1 时,Weibull 密度函数增加到一个模式,然后减小,因此您可能需要从两个均匀区间中提取特定的最小值和最大值(因为 W 和 U 的反转可能会给出两个答案)。

【讨论】:

@user:16757174 谢谢。你从哪里得到 W 方程?我想了解它 @mahmoudihocine 这个方程可以在很多地方找到;我在 wikipedia article for "Weibull Distribution" 上看到了这个,但同样的方程出现在 numpy.random.weibull 的 numpy 文档中,或者 python 的 random.weibullvariate 的源代码中,它使用公式生成值。跨度> 是否可以将这个想法用于离散分布? @mahmoudihocine 我不知道有什么方法,但我以前没有使用过离散威布尔分布。要使用这个想法,您需要找到一个更常见的随机分布,该分布可以转换为离散威布尔。由于 NumPy 中已经内置了 Weibull 生成器,我建议您查看一个实际的科学计算包【参考方案2】:

您的问题不是很清楚,为什么您认为使用此 Weibull 分布是一个好主意,也不清楚您希望实现哪种分布。

离散均匀分布

这里有两种方法可以在[700, 1200)上实现离散均匀分布。

1) 与random

import random

nums = [random.randrange(700, 1200) for _ in range(100)]

2) 与numpy

import numpy

nums = numpy.random.randint(700, 1200, 100)

几何分布

您已经使用示例直方图编辑了您的问题,并提到“我想生成一个像这样的直方图”。直方图隐约看起来像geometric distribution。

我们可以使用numpy.random.geometric:

import numpy

n_samples = 100
p = 0.5
a, b = 50, 650
cap = 1200

nums = numpy.random.geometric(p, size = 2 * n_samples) * a + b
nums = nums[numpy.where(nums < cap)][:n_samples]

【讨论】:

我希望 weibull 分布生成故障率数据。就像在这个直方图中i.stack.imgur.com/jq83c.png @mahmoudihocine 好吧,那么我猜你需要调整 weibull 分布公式的参数 alpha 和 beta,使其适合 [700, 1200) @user:3080723 感谢您的帮助。你有关于如何找出正确参数的资源吗?我应该谷歌什么? @mahmoudihocine 我不知道。你为什么要首先使用威布尔分布?你在某处读过它吗?这将是一个很好的起点。 @mahmoudihocine, alpha 是比例参数。增加alpha 的值会将分布向右拉伸。您可以通过增加 alpha 来增加 [700, 1200) 内随机值的可能性。请注意,这确实对您正在建模的任何内容的可靠性特性产生重大影响。如果您希望您的分布匹配它,您需要找到用于创建示例分布的参数。

以上是关于如何让这个 python 代码运行得更快?的主要内容,如果未能解决你的问题,请参考以下文章

让Python跑得更快

如何让已经运行的 PL SQL 包运行得更快?

如何让我的 python 程序运行得更快?

如何使此代码运行得更好/更快(线程或多处理)?怎么做?

如何让python程序运行得更快

如何让这个查询在 postgres 中运行得更快