Generieren Sie ein zufälliges Array von Floats zwischen einem Bereich

89

Ich konnte keine Funktion finden, um ein Array von zufälligen Floats einer bestimmten Länge zwischen einem bestimmten Bereich zu generieren.

Ich habe mir Zufallsstichproben angesehen, aber keine Funktion scheint das zu tun, was ich brauche.

random.uniform kommt nahe, gibt aber nur ein einzelnes Element zurück, keine bestimmte Zahl.

Das ist was ich will:

ran_floats = some_function(low=0.5, high=13.3, size=50)

Dies würde ein Array von 50 zufälligen nicht eindeutigen Floats zurückgeben (dh Wiederholungen sind zulässig), die gleichmäßig im Bereich verteilt sind [0.5, 13.3].

Gibt es eine solche Funktion?

Gabriel
quelle
5
Sie haben die Frage markiert numpy, aber nicht erwähnt numpy.random.uniform, obwohl sie genau die gewünschte Anrufsignatur enthält. Haben Sie die numpyBibliothek zur Verfügung?
DSM
1
[random.uniform(low, high) for i in xrange(size)]
Phylogenesis
1
@DSM ja ich habe und du bist anscheinend 100% korrekt. Ich habe diese Funktion verpasst und sie scheint genau das zu tun, was ich brauche. Würde es Ihnen etwas ausmachen, Ihren Kommentar als Antwort zu präsentieren?
Gabriel

Antworten:

141

np.random.uniform passt zu Ihrem Anwendungsfall:

sampl = np.random.uniform(low=0.5, high=13.3, size=(50,))

Update Oktober 2019:

Obwohl die Syntax weiterhin unterstützt wird, scheint die API mit NumPy 1.17 geändert worden zu sein, um eine bessere Kontrolle über den Zufallszahlengenerator zu ermöglichen. In Zukunft hat sich die API geändert und Sie sollten sich https://docs.scipy.org/doc/numpy/reference/random/generated/numpy.random.Generator.uniform.html ansehen

Der Verbesserungsvorschlag ist hier: https://numpy.org/neps/nep-0019-rng-policy.html

JoshAdel
quelle
23
Die intuitive Suchfrage von OP lautet some_function(low=0.5, high=13.3, size=50). So gut sind Python-Bibliotheken gestaltet #wow
Saravanabalagi Ramachandran
Größe war nicht ganz klar und Link funktioniert nicht. Hier ist eine kleine Klarstellung. Größe: Int oder Tupel von Ints, optional. Ausgabeform. Wenn die gegebene Form z. B. (m, n, k) ist, werden m * n * k Proben gezogen. Wenn Größe keine Standardeinstellung ist, wird ein einzelner Wert zurückgegeben, wenn sowohl niedrig als auch hoch Skalare sind.
Vlad
@vlad - danke, dass du auf das Problem mit dem Link hingewiesen hast. Ich habe die Antwort aktualisiert, um hoffentlich die aktuelle Verwendung abzudecken.
JoshAdel
20

Warum nicht ein Listenverständnis verwenden?

In Python 2

ran_floats = [random.uniform(low,high) for _ in xrange(size)]

Funktioniert in Python 3 rangewie xrange( ref )

ran_floats = [random.uniform(low,high) for _ in range(size)]
isedev
quelle
3

Warum nicht random.uniform mit einem Listenverständnis kombinieren ?

>>> def random_floats(low, high, size):
...    return [random.uniform(low, high) for _ in xrange(size)]
... 
>>> random_floats(0.5, 2.8, 5)
[2.366910411506704, 1.878800401620107, 1.0145196974227986, 2.332600336488709, 1.945869474662082]
pkacprzak
quelle
3

Möglicherweise gibt es bereits eine Funktion, mit der Sie das tun können, wonach Sie suchen, aber ich weiß (noch) nichts darüber. In der Zwischenzeit würde ich empfehlen:

ran_floats = numpy.random.rand(50) * (13.3-0.5) + 0.5

Dies erzeugt eine Formanordnung (50,) mit einer gleichmäßigen Verteilung zwischen 0,5 und 13,3.

Sie können auch eine Funktion definieren:

def random_uniform_range(shape=[1,],low=0,high=1):
    """
    Random uniform range

    Produces a random uniform distribution of specified shape, with arbitrary max and
    min values. Default shape is [1], and default range is [0,1].
    """
    return numpy.random.rand(shape) * (high - min) + min

EDIT : Hmm, ja, also habe ich es verpasst, es gibt numpy.random.uniform () mit genau dem Aufruf, den Sie wollen! Versuchen Sie es import numpy; help(numpy.random.uniform)mit weiteren Informationen.

PhilMacKay
quelle
3

Die for-Schleife beim Listenverständnis braucht Zeit und macht sie langsam. Es ist besser, numpy-Parameter zu verwenden (niedrig, hoch, Größe, usw.)

import numpy as np
import time
rang = 10000
tic = time.time()
for i in range(rang):
    sampl = np.random.uniform(low=0, high=2, size=(182))
print("it took: ", time.time() - tic)

tic = time.time()
for i in range(rang):
    ran_floats = [np.random.uniform(0,2) for _ in range(182)]
print("it took: ", time.time() - tic)

Beispielausgabe:

('es dauerte:', 0.06406784057617188)

('es dauerte:', 1.7253198623657227)

Mohamed Ibrahim
quelle
3

Alternativ können Sie SciPy verwenden

from scipy import stats
stats.uniform(0.5, 13.3).rvs(50)

und damit der Datensatz ganze Zahlen abtastet, ist es

stats.randint(10, 20).rvs(50)
Stuart Hallows
quelle
2

Dies ist der einfachste Weg

np.random.uniform(start,stop,(rows,columns))
George Gee
quelle
-1

np.random.random_sample(size) erzeugt zufällige Floats im halboffenen Intervall [0.0, 1.0].

Shivaraj Karki
quelle