Numpy'de tekrar etmeyen rastgele sayı


92

Numpy'de tekrar etmeyen rastgele sayıları nasıl üretebilirim?

list = np.random.random_integers(20,size=(10))

"Tekrarlamayan" derken neyi kastediyorsunuz? Rastgele sayı dizisinin asla yinelenmediğini mi? Rastgele sayı üretecinin durumunun bir bilgisayarın sonlu belleğine sığması gerektiğinden, bu mümkün değildir. Yoksa tek bir sayının iki kez oluşmadığını mı söylüyorsunuz?
Sven Marnach

5
Yinelemeyen, yinelenmeyen bir listeniz olduğu anlamına gelir.
Polinom

2
Belki de rastgele bir permütasyona ihtiyacınız var? docs.scipy.org/doc/numpy/reference/generated/…
cyborg

Yanıtlar:


112

numpy.random.Generator.choicereplacedeğiştirilmeden örnekleme için bir argüman sunar :

from numpy.random import default_rng

rng = default_rng()
numbers = rng.choice(20, size=10, replace=False)

GeneratorAPI olmadan 1.17 öncesi bir NumPy kullanıyorsanız random.sample(), standart kitaplıktan kullanabilirsiniz:

print(random.sample(range(20), 10))

Ayrıca kullanabilir numpy.random.shuffle()ve dilimleyebilirsiniz, ancak bu daha az verimli olacaktır:

a = numpy.arange(20)
numpy.random.shuffle(a)
print a[:10]

replaceEski numpy.random.choiceişlevde de bir argüman var , ancak bu argüman verimsiz bir şekilde uygulandı ve ardından rastgele sayı akışı kararlılığı garantileri nedeniyle verimsiz kaldı, bu nedenle kullanımı önerilmez. (Temelde karıştırma ve dilimleme işini dahili olarak yapar.)


1
print random.sample (range (20), 10) python 2.6 ile çalışmıyor mu ?!
Academia

Sorun, kötü bir Pydev yapılandırmasından kaynaklanıyordu. Thks
Academia

1
Ya n değerim 20 değilse, 1000000 gibiyse ve ondan sadece 10 benzersiz sayıya ihtiyacım varsa, daha verimli bellek yaklaşımı var mı?
mrgloom

2
@mrgloom Python 3'te, bir nesne başlangıç, bitiş ve adım değerlerini depolayan küçük bir sarmalayıcı olduğundan, ancak tam sayıların tam listesini oluşturmadığından, random.sample(range(n), 10))çok büyükler için bile verimli olacaktır . Python 2'de, benzer bir davranış elde etmek için ile değiştirebilirsiniz . nrangerangexrange
Sven Marnach

110

Sanırım numpy.random.sampleşu anda çalışmıyor. Bu benim yolum:

import numpy as np
np.random.choice(range(20), 10, replace=False)

26
İlk argüman olarak range(n)(veya arange(n)) yerine, choicesadece pass'a eşdeğerdir n, örn choice(20, 10, replace=False).
Josh Bode

1
Bunun np.random.choice(a, size, replace=False)büyük için çok yavaş olduğunu unutmayın a- makinemde a = 1M için yaklaşık 30 ms.
Matthew Rahtz

3
Çok uzun nnumpy.random.Generator.choice
süreli

1
Gördüğüm ana dezavantaj, np.random.choice'un bir eksen parametresine sahip olmaması -> sadece 1d dizileri için.
Moosefeather

3

Yıllar sonra, 10000 ^ 2'den 40000'ü seçmek için bazı zamanlar (Numpy 1.8.1, imac 2.7 GHz):

import random
import numpy as np

n = 10000
k = 4
np.random.seed( 0 )

%timeit np.random.choice( n**2, k * n, replace=True )  # 536 µs ± 1.58 µs
%timeit np.random.choice( n**2, k * n, replace=False ) # 6.1 s ± 9.91 ms

# https://docs.scipy.org/doc/numpy/reference/random/index.html
randomstate = np.random.default_rng( 0 )
%timeit randomstate.choice( n**2, k * n, replace=False, shuffle=False )  # 766 µs ± 2.18 µs
%timeit randomstate.choice( n**2, k * n, replace=False, shuffle=True )   # 1.05 ms ± 1.41 µs

%timeit random.sample( range( n**2 ), k * n )          # 47.3 ms ± 134 µs

(Neden 10000 ^ 2 üzerinden 40000'ü seçmelisiniz ? Büyük scipy.sparse.random matrisleri oluşturmak için - scipy 1.4.1 kullanır np.random.choice( replace=False ), slooooow.)

Şapkanın ucu uyuşmuş insanlara.


1

Bunu sıralayarak da elde edebilirsiniz:

random_numbers = np.random.random([num_samples, max_int])
samples = np.argsort(random_numbers, axis=1)

0

Python set listesi dönüşümü kullanılabilir. 0 ile 20 arasında 10 benzersiz sayı şu şekilde elde edilebilir:

import numpy as np
import random
unique_numbers=set()
while(len(unique_numbers)<10):
    unique_numbers.add(np.random.randint(0,20))

unique_numbers=list(unique_numbers)
random.shuffle(unique_numbers)
print(unique_numbers)

-3

Basitçe, gerekli sayı aralığını içeren bir dizi oluşturun, ardından rastgele bir tanesini dizideki 0. elemanla tekrar tekrar değiştirerek bunları karıştırın. Bu, yinelenen değerler içermeyen rastgele bir dizi üretir.


2
Elde edilen rastgele dizinin bir başka özelliği, özellikle rastgele olmamasıdır .
Sven Marnach

@SvenMarnach - Çoğu amaç için yeterince rastgele. Daha rastgele isterse çift rastgele yaklaşımı kullanabilirdi.
Polinom

Bu anlamsız. OP, bunu doğru yapmak için kütüphane çağrılarını kullanabilir. Özel bir sürüme göre kullanımı daha kolaydır, daha hızlı çalışır ve daha okunabilirdir. Burada yanlış bir algoritma kullanmam için herhangi bir neden düşünemiyorum, çünkü muhtemelen "yeterince rastgele", doğru algoritmayı kullanmanın hiçbir dezavantajı yok.
Sven Marnach

@SvenMarnach - Yeterince adil. Uyuşuk olduğunu bilmiyorum, bu yüzden sadece potansiyel bir çözüm öneriyordum.
Polinom
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.