sample from randomly generated numbers?

Question:

There is a program that needs to get 100 samples from 1000 randomly generated number distributed in [1, 500]. How can do I get a random sample from the output?

I wrote the following:

N = 1000
x = 1 + 500 * np.random.rand(N) 
sp_x = random.sample(x, 100)

I am getting an error:

TypeError: Population must be a sequence or set.  For dicts, use list(d).
Asked By: Hana S

||

Answers:

For some reason, random.sample is misidentifying the sequence. You can easily fix this by forcing a conversion of the input to a list type.

sp_x = random.sample(list(x), 100)

This is why EAFP is such an important principle in Python – if random.sample had simply tried to iterate on the input, it would have succeeded. Instead it checked the type and failed when it wasn’t an expected iterable type.

Answered By: Mark Ransom

From your code, the resulting x is a numpy array.
To check type(x) output: numpy.ndarray

But the function random.sample(sequence, k) can only take in a sequence that is a list, tuple, string, or set. So your code could be:

import random
N = 1000
x = 1 + 500*np.random.rand(N) 
x = list(x)
sp_x = random.sample(x, 100)
print(len(sp_x))

output: 100

Answered By: perpetualstudent

The standard library random module, and in particular random.sample, is not really intended to work with numpy. Since you’re using arrays, stick with numpy routines since they are generally much more efficient.

To generate the first array more simply, use np.random.uniform:

x = np.random.uniform(1, 500, size=N)

You can sample the 100 items in a number of ways in numpy. A very basic method is to apply np.random.shuffle to x and slice off the first 100 elements:

np.random.shuffle(x)
sp_x = x[:100]

Another option is to usenp.random.choice:

sp_x = np.random.choice(x, 100, replace=False)

All of the above is using the legacy API. The new Generator API is preferred and generally much more efficient.

gen = np.random.default_rng()
x = gen.uniform(1, 500, size=N)
sp_x = gen.choice(x, 100, replace=False)

Keep in mind that using np.random.rand, random.uniform and random.Generator.uniform selects floating point values on the interval [1, 500). If you wanted to generate integers in [1, 500] instead, do something like

x = np.random.randint(1, 501, size=N)

Or

x = gen.integers(500, endpoint=True, size=N)
Answered By: Mad Physicist
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.