65 votes

Randint ne suit pas toujours la distribution uniforme

J'ai été à jouer avec l'aléatoire de la bibliothèque Python pour simuler un projet sur lequel je travail et je me suis retrouvé dans une drôle de position.

Disons que nous avons le code suivant en Python:

from random import randint
import seaborn as sns

a = []
for i in range(1000000):
    a.append(randint(1,150))

sns.distplot(a)

L'intrigue suit un "uniforme discrète" de distribution comme il se doit.

Range betwee 1 and 150

Cependant, lorsque je change la gamme de 1 à 110, la parcelle a plusieurs pics.

from random import randint
import seaborn as sns

a = []
for i in range(1000000):
    a.append(randint(1,110))

sns.distplot(a)

Range from 1 to 110

Mon impression est que les sommets sont sur 0,10,20,30,... mais je ne suis pas capable de l'expliquer.

Edit: La question n'était pas similaire à celui proposé en double, puisque le problème dans mon cas, c'était le seaborn de la bibliothèque et de la façon dont je la visualisation de données.

Edit 2: en Suivant les suggestions sur les réponses, j'ai essayé de le vérifier par la modification de la seaborn de la bibliothèque. Au lieu de cela, à l'aide de matplotlib les deux graphes ont été les mêmes

from random import randint
import matplotlib.pyplot as plt

a = []
for i in range(1000000):
    a.append(randint(1,110))

plt.hist(a) 

From matplotlib

123voto

Rory Daulton Points 11787

Le problème semble être dans votre grapher, seaborn, pas en randint().

Il y a 50 bacs de rangement dans votre seaborn diagramme de diffusion, selon mon décompte. Il semble que seaborn est en fait binning retournés randint() valeurs dans les bacs, et il n'y a aucun moyen d'obtenir une répartition homogène de 110 valeurs dans 50 bacs. Par conséquent, vous obtenez ces sommets où trois valeurs se mettre dans une poubelle plutôt que deux valeurs pour les autres bacs. Les valeurs de vos pics de le confirmer: ils sont 50% plus élevés que dans les autres bars, comme prévu pour 3 mise à la poubelle des valeurs plutôt que pour les 2.

Une autre façon pour vous de vérifier cela est de forcer seaborn à 55 bacs pour ces 110 valeurs (ou peut-être 10 bacs ou une autre diviseur de 110). Si vous obtenez toujours les sommets, alors vous devriez vous inquiéter randint().

21voto

John Coleman Points 4693

Pour ajouter à @RoryDaulton 's réponse excellent, j'ai couru randint(1:110), générant une fréquence de comptage et de le convertir en un R-vectoriel de compte comme ceci:

hits = {i:0 for i in range(1,111)}
for i in range(1000000): hits[randint(1,110)] += 1
hits = [hits[i] for i in range(1,111)]
s = 'c('+','.join(str(x) for x in hits)+')'
print(s)

c(9123,9067,9124,8898,9193,9077,9155,9042,9112,9015,8949,9139,9064,9152,8848,9167,9077,9122,9025,9159,9109,9015,9265,9026,9115,9169,9110,9364,9042,9238,9079,9032,9134,9186,9085,9196,9217,9195,9027,9003,9190,9159,9006,9069,9222,9205,8952,9106,9041,9019,8999,9085,9054,9119,9114,9085,9123,8951,9023,9292,8900,9064,9046,9054,9034,9088,9002,8780,9098,9157,9130,9084,9097,8990,9194,9019,9046,9087,9100,9017,9203,9182,9165,9113,9041,9138,9162,9024,9133,9159,9197,9168,9105,9146,8991,9045,9155,8986,9091,9000,9077,9117,9134,9143,9067,9168,9047,9166,9017,8944)

J'ai ensuite collé à un R-console, reconstruit les observations et utilisé R hist() sur le résultat, l'obtention de cet histogramme (avec superposition de la densité de la courbe):

enter image description here

Comme vous pouvez le voir, cela confirme que le problème que vous avez observé n'est pas traçable randint mais est un artefact de l' sns.displot().

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X