簡體   English   中英

random.randint 的加權版本

[英]A weighted version of random.randint

我想在ab (都包括在內)之間選擇一個隨機整數,統計權重為c

c是之間的值ab

將權重因子c應用於 random.randint 的最有效方法是什么?

我得到的最接近的是這個問題,但有很大的不同:

我只有一個統計權重c ,而不是ab之間a每個值的統計概率。

例子:

a = 890
b = 3200

c = 2600

print(random.randint(a,b))

>>>> supposed to result most frequently in a value around 2600

我並不真正關心ab之間的分布,只要cc重。 然而,高斯分布將不勝感激。

請注意:這個問題不會沒有解決numpy.random模塊在這一問題。

聽起來三角分布可能適合您的需求。 ab分別是最小最大,和c對應於分布的(最可能的結果)。

numpy.random有一個三角形生成器。 它生成浮點數,但您可以四舍五入,然后將結果整數化。 如果您很挑剔,這將略微偏離最小值和最大值,與其他整數值相比,它們只有一半的范圍,因此只有一半的預期計數。 統計學家使用連續性校正來調整從實數到整數的范圍轉換:從最小值減去 1/2,將 1/2 添加到最大值。 如果您正在處理小范圍,這很可能是相關的,如下面的小示例所示。

import numpy as np
import matplotlib.pyplot as plt

# replace with your actual values
a = 1
b = 5
c = 2

# Without continuity correction
plt.hist(np.ma.round(np.random.triangular(
          left = a,
          mode = c,
          right = b, 
          size = 100000)
        ).astype(int),
        range = (0.5, 5.5), bins = 50, density = True)
plt.show()

# With continuity correction
plt.hist(np.ma.round(np.random.triangular(
          left = a - 0.5,
          mode = c,
          right = b + 0.5, 
          size = 100000)
        ).astype(int),
        range = (0.5, 5.5), bins = 50, density = True)
plt.show()

以下是實際參數化的結果:

# Actual target case
a = 890
b = 3200
c = 2600
plt.hist(np.ma.round(np.random.triangular(
          left = a - 0.5,
          mode = c,
          right = b + 0.5, 
          size = 100000)
        ).astype(int),
        range = (500, 3500), bins = 300, density = True)
plt.show()

生成的三角形分布的直方圖

請注意,與評論中建議的正態分布不同,這保證保持在(a, b)范圍內。

你用

random.choices(range(a,b+1), weights= [....], k=1)  # or cum_weights

對於k為 1 和range(a,b+1)的總體以及您想要的權重。

請參閱: https : //docs.python.org/3/library/random.html#random.choices


您必須計算可能的(任意)權重 fe:

import random
from collections import defaultdict
a = 8
b = 32

c = 26

# hacked distribution
w = [(i-a)**2 if i <= c else (b-i+a)**2 for i in range(a,b+1)]

d=defaultdict(int)
for i in range(a,b+1):
    d[i]=0

# test for 10k numbers
for num in random.choices(range(a,b+1), weights = w, k=10000):
    d[num] += 1

print(w)
print(d)

它仍然是隨機的,一次運行讓我:

# hacked distribution
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 
  256, 289, 196, 169, 144, 121, 100, 81, 64]

# test for 10k numbers
{8: 0, 9: 8, 10: 7, 11: 37, 12: 61, 13: 94, 14: 149, 15: 175, 16: 229, 
 17: 283, 18: 374, 19: 450, 20: 493, 21: 628, 22: 672, 23: 820, 24: 907, 
 25: 1038, 26: 1183, 27: 564, 28: 537, 29: 435, 30: 325, 31: 293, 32: 238}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM