Suraj Kothari
Suraj Kothari

Reputation: 1632

Numpy empty array changes value after creating normal array

I read on the official numpy page that there was an alternative to creating an initialised array without using just zeros:

empty, unlike zeros, does not set the array values to zero, and may therefore be marginally faster.

I created two functions below that demonstrate an unusual issue with using this function:

import numpy as np

def getInitialisedArray():
    return np.empty((), dtype=np.float).tolist()

def createFloatArray(x):
    return np.array(float(x))

If I just call getInitialisedArray() on its own, here is what it outputs:

>>> getInitialisedArray()
0.007812501848093234

And if I just call the createFloatArray() function:

>>> createFloatArray(3.1415)
3.1415

This all seems fine, but if I repeat the test and call the getInitialisedArray() after creating the float array, there is an issue:

print(getInitialisedArray())
print(createFloatArray(3.1415))
print(getInitialisedArray())

Output:

>>>
0.007812501848093234
3.1415
3.1415

It seems the second call to get an initialised array gets the same value as what was put in the normal np.array(). I don't get why this occurs. Shouldn't they be separate arrays that have no link between each other?

--- Update ---

I repeated this and changed the size of the empty array:

import numpy as np

def getInitialisedArray():
    # Changed size to 2 x 2
    return np.empty((2, 2), dtype=np.float).tolist()

def createFloatArray(x):
    return np.array(float(x))

print(getInitialisedArray())
print(createFloatArray(3.1415))
print(getInitialisedArray())

Output:

[[1.6717403e-316, 6.9051865033801e-310], [9.97338022253e-313, 2.482735075993e-312]]
3.1415
[[1.6717403e-316, 6.9051865033801e-310], [9.97338022253e-313, 2.482735075993e-312]]

This is the sort of output I was expecting, but here it works because I changed the size. Does size now affect if an empty array takes on the same value of a normal np.array()?

Upvotes: 0

Views: 995

Answers (2)

Andrei Tsitsvidze
Andrei Tsitsvidze

Reputation: 43

Check id() for each array after initializing it. np.empty() creates space that later can be used after initializing array of the same shape.

for more understanding: print(np.array(float(1)) print(np.empty((),dtype=np.float).tolist())

same thing but assigning to variables: x = np.array(float(1)) y = np.empty((),dtype=np.float).tolist() print(x) print(y)

Upvotes: 0

blackdrumb
blackdrumb

Reputation: 320

From the documentation, np.empty() will "return a new array of given shape and type, without initializing entries." This should mean that it will just allocate a space in memory for the variable it is assigned to. Whatever the data in the memory space is will not be changed.

In the first example, you are printing the return from getInitialisedArray without actually storing it. Python must then know you didn't store the address of that value. Then python will keep that address for the next value that needs an address. Since createFloatArray does not store the address as well, the value in the address will be changed to 3.1415, and python will keep the address for the next assignment. When you call getInitialisedArray again, it will use that address again and print out 3.1415. If you change the datatype however (such as changing the dimensions of the array), depending on how python handles that datatype, it might need more blocks of memory and have to get a different address. In theory, if createFloatArray was the same shape as getInitialisedArray, it could have the same behavior.

WARNING! I would highly recommend not doing this. It is possible that python or your system in general will perform a task between those two operations which would change the memory address between calls even if it is the same datatype.

Upvotes: 1

Related Questions