Can I specify a numpy dtype when generating random values?
Asked Answered
C

4

49

I'm creating a numpy array of random values and adding them to an existing array containing 32-bit floats. I'd like to generate the random values using the same dtype as the target array, so that I don't have to convert the dtypes manually. Currently I do this:

import numpy as np

x = np.zeros((10, 10), dtype='f')
x += np.random.randn(*x.shape).astype('f')

What I'd like to do instead of the last line is something like:

x += np.random.randn(*x.shape, dtype=x.dtype)

but randn (and actually none of the numpy.random methods) does not accept a dtype argument.

My specific question is, is it possible to specify a dtype for random numbers when I create them, without having to call astype? (My guess is that the random number generator is 64 bits long, so it doesn't really make sense to do this, but I thought I'd ask if it's possible.)

Constitution answered 29/4, 2014 at 4:23 Comment(1)
numpy will automatically convert the type of your random array to the type of x when you do the operation in-place, there's absolutely no need for astype, simply do x += np.random.randn(*x.shape), and see for yourself that x.dtype doesn't change.Platelayer
B
38

Q: is it possible to specify a dtype for random numbers when I create them.

A: No it isn't. randn accepts the shape only as randn(d0, d1, ..., dn)

Simply try this:

x = np.random.randn(10, 10).astype('f')

Or define a new function like

np.random.randn2 = lambda *args, dtype=np.float64: np.random.randn(*args).astype(dtype)
x = np.random.randn2(10, 10, dtype='f')

If you have to use your code on the post, try this code instead

x = np.zeros((10, 10), dtype='f')
x[:] = np.random.randn(*x.shape)

This assigns the results of randn to the memory allocated by np.zeros

Blinni answered 29/4, 2014 at 4:28 Comment(4)
this does not work for the case of scalars (e.g. randn()) because randn will return a float numeric type, not an array - otherwise, basically what I did as wellIamb
This does not seem to work for .astype('i') as it gives a matrix with all elements as 0.Soloma
you can use the usual np.float32 or np.int in astype as wellMotorcade
@Soloma integers works fine for me. note that ~68% of them will be zero. i.e. it truncates values towards zero, so only ~16% of the distribution will be less than -1 and ~16% above +1Absinthism
I
13

Let me begin by saying that numpy now supports dtypes for random integers. This enhancement can be tracked through Issue #6790 on numpy's github. But as of today, this facility is not available for the gaussian RNG. I needed this same facility so I wrote this patch for numpy, https://gist.github.com/se4u/e44f631b249e0be03c21c6c898059176

The patch only adds support for generating float values and it does not handle other data types, but it might still be helpful to someone.

UPDATE 27 Sep 2020

The numpy.random.Generator provides RNGs that support the dtype keyword for all random variables. E.g. numpy.random.default_rng().standard_normal(size=1, dtype='float32') gives 1 standard gaussian of type float32.

Invisible answered 1/1, 2017 at 18:21 Comment(4)
This seems to only apply to certain random distributions, Poisson for example doesn't have this argument: numpy.org/doc/stable/reference/random/generated/…Dorindadorine
poisson distribution is over natural numbers not reals.Invisible
Well, how about uniform then: numpy.org/doc/stable/reference/random/generated/…Dorindadorine
It seems you have to use a different function called random. e.g. import numpy; numpy.random.default_rng().random(1, dtype='float32') works. But yes in general your point is right that not all the distributions support it, like standard_tInvisible
T
1

I guess often you can simply use randint, e.g.

np.random.randint(low=0, high=256, size=(256,256,3), dtype=np.uint8)
Tifanie answered 9/12, 2022 at 14:18 Comment(0)
V
-5

np.random.randn function randomly initializes the array object of a given shape to a "np.float64" You can find this out yourself by doing as follows:

a = np.random.rand(2,3)
b = a[1,2]
print (type(b))
print (type(a))

output as follows:

<class 'numpy.float64'>
<class 'numpy.ndarray'>
Voltmer answered 1/4, 2018 at 8:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.