1

Numpy's random.rand() function produces random floats between 0 and 1. How do I transform the output of this function to produce random floats between -1 and 1?

Current output:

In[]: numpy.random.rand(3, 2)
Out[]: 
array([[0.13568674, 0.72465483],
       [0.48726461, 0.68867378],
       [0.50463821, 0.28619853]])

Desired (example) output:

In[]: numpy.random.rand(3, 2)
Out[]: 
array([[-0.13568674, 0.72465483],
       [-0.48726461, 0.68867378],
       [0.50463821, -0.28619853]])

I would not like to use random.uniform().

2
  • 4
    (numpy.random.rand(3, 2) - 0.5) * 2 Commented Dec 18, 2019 at 9:45
  • 1
    What's the reason not to use np.random.uniform? That's an odd restriction; do you have a good reason for avoiding it, and are there other, similar restrictions? You seem be operating under an unusual set of constraints, and it would be useful to know what those are. Commented Dec 18, 2019 at 11:18

2 Answers 2

3

You basically need to scale and shift the (0, 1) range normally generated by np.random.rand() to the (-1, 1) target range:

import numpy as np

N = 10
max_val, min_val = 1, -1
range_size = (max_val - min_val)  # 2
np.random.rand(N) * range_size + min_val

or other equivalent algebra.


Alternatively, you could use np.random.randint() to generate a int range to be divided by (a fraction of) its size.

For your specific range, this would look like:

import numpy as np


N = 10
L = 100
np.random.randint(-L, L, N) / L

This would be (slightly) slower than the np.random.random() approach, but would give you control over the "density" of the result.


(EDITED: explicitly write the relationship between the algebra and the target range)

Sign up to request clarification or add additional context in comments.

1 Comment

The second option will create a more stratified or binned random sampling, since there are only 200/10 = 20 possible values now. This gives the control over density. However, this may or may not be applicable to the specific use-case. The best thing, perhaps is to apply np.random.rand and then use some form of binning if necessary. But yes, both methods could be applicable ways of sampling in some scenarios. If someone is blindly applying uniform random sampling, I would suggest to use the first method.
1

If you want to generate a random float between two values a and b, where a < b, then it is done as follows. This is equivalent to redistributing or re-scaling the random-distribution between [0,1] to the desired interval [a,b] (equivalent to stretching or compressing, depending on whether (b - a) is <, = or > (1 - 0).

import numpy as np
# in your case:
a, b = -1, 1
(b - a)*np.random.rand() + a

1 Comment

This is correct, are the same instructions provided in the official documentation. Quote: (...). To sample Unif[a, b), b > a multiply the output of random by (b-a) and add a. (...)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.