0

I feel like this can be easily accomplished. I have the following code:

my_array =   np.zeros(6)
min =      0
max =      1

my_array = np.random.uniform(min,max, my_array.shape)
print(my_array)

I might be wrong, but I think np.random.uniform() generates a whole new array, and then the my_array variable simply points to the new array, while the old array gets garbage collected. Since I'm positive that the new array will have the same shape of the old one, is there a way to efficiently replace the values, rather than allocating a whole new array. Furthermore, I hope I could do this efficiently, such that I don't need to use for loops. The following code was my attempt:

my_array[:] = np.random.uniform(min,max)

However, this results in a single new random value that gets reproduced 6 times, which is not what I want, and, furthermore, probably results in 6 calls to np.random.uniform() which seems inefficient

EDIT: I want to keep the same functionality as in the code above, i.e., I want to replace all values of the array with new, random, values. The idea is to do this multiple times which is why I want to avoid having to generate a new array each time

  • do you want to replace the values inside the array based on certain condition ? – Shubham Shaswat Apr 14 '21 at 14:21
  • @ShubhamShaswat no, I want to maintain the functionality that I presented in my example code. I.e. I want to replace all values with new values randomly distributed between 0 and 1, unconditionally – Carlos Pinto Apr 14 '21 at 14:39
  • 1
    `myarray[:]=np.random...` does a replace. But `random` may still make a temporary new buffer array. Some functions have an `out` parameter that may skip that buffer step. – hpaulj Apr 14 '21 at 14:48
  • @hpaulj hmm, np.random...() doesn't seem to have an out parameter. I feel like there's likely a function that takes in the array as input and changes it directly, but I just can't find it – Carlos Pinto Apr 14 '21 at 14:53

1 Answers1

0

One can replace the values of one numpy array with the values of another numpy array using the syntax

original_array[...] = array_of_new_values

The ... is an Ellipsis. See https://stackoverflow.com/a/118508/5666087 for more information. As hpaulj comments, some numpy functions provide an out= argument, so values from the function can go directly into the existing array. np.random.uniform does not have this argument.

I have provided an example below.

import numpy as np

arr = np.zeros((100, 100, 100))

And now we overwrite the values:

low, high = 0, 1
arr[...] = np.random.uniform(low, high, arr.shape)

Here are timeit results of overwriting an existing array and creating a new variable:

%timeit arr[...] = np.random.uniform(0, 1, arr.shape)
# 67 ms ± 6.62 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
arr2 = np.random.uniform(0, 1, arr.shape)
# 85.3 ms ± 10.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
jkr
  • 17,119
  • 2
  • 42
  • 68
  • This is interesting, goes to show that I have little to no clue how Python works underneath. This is exactly what I wanted but I fail to realize how Python/NumPy seems to "guess" that the values of the rand() function will be used to overwrite something rather than to create a new variable, such that this interpretation would have to be done inside the function itself. Thanks! – Carlos Pinto Apr 14 '21 at 14:58
  • In my testing the `arr[...]=` version is slower, the same as if I had an explicit temporary variable, `b=np.random...; arr[...]=b`. My timings are 4x faster, and my computer is pretty basic, so there may be some memory or system differences. – hpaulj Apr 14 '21 at 15:48
  • @hpaulj - i used the hosted jupyterlab at https://jupyter.org/try. from my limited understanding of what's happening, i would expect both `b=np.random...` and `a[...]=np.random...` to have roughly the same time. is that fair to say? – jkr Apr 14 '21 at 18:23