如何让这个 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 代码运行得更快?的主要内容,如果未能解决你的问题,请参考以下文章