user3389669
user3389669

Reputation: 809

Python: Replace every value in a NumPy array with a similar one

Consider the following random function which returns nearly the same number it received (it returns a sample from the Gaussian distribution with mean x and standard deviation of 0.001 * x):

def similar(x, rel_std=0.001):
    sigma = rel_std * x
    mu = x
    return sigma * np.random.randn() + mu

So for example:

> print(similar(1.0))
0.99946018

This function seems to be applicable to arrays of arbitrary shape:

> ones = np.ones(5)
> print(similar(ones))
[0.99946018 0.99946018 0.99946018 0.99946018 0.99946018]

> example = np.array([[[6,7,8,9,10],[-1,-2,-3,-4,-5]],[[1,2,3,4,5], [-2,-1,0,1,2]]])
> print(similar(example))
[[[ 6.00610123  7.0071181   8.00813497  9.00915185 10.01016872]
  [-1.00101687 -2.00203374 -3.00305062 -4.00406749 -5.00508436]]

 [[ 1.00101687  2.00203374  3.00305062  4.00406749  5.00508436]
  [-2.00203374 -1.00101687  0.          1.00101687  2.00203374]]]

However, as you might have noticed, it does not use for every cell a new random seed. What I am looking for is a function which uses randomness for every cell of an arbitrarily shaped NumPy array. Since the shape may be of any kind, I think nested for-loops are not usable.

An additional requirement is that the approach should work reasonably fast even for arrays of shape (1024, 1024). Is there a way of writing a fast (e. g. by vectorizing) function performing the mentioned task?

EDIT: I don't mind to change the definition of similar, or to use a function of different interface – as long as the suggestion fits the purpose of producing a »similar« matrix.

Upvotes: 0

Views: 135

Answers (1)

ec2604
ec2604

Reputation: 521

I don't think your similar function works the way you think it does. Your function generates a single random number*sigma (which is a scalar) and adds this same scalar to all the cells in your mu == x.

Changing np.random.randn to output a randn matrix having the shape of x should solve the problem.

def similar(x, rel_std=0.001):
    sigma = rel_std * x
    mu = x
    return sigma * np.random.randn(*x.shape) + mu

Upvotes: 1

Related Questions