Perform numpy exp function in-place
Asked Answered
P

2

6

As in title, I need to perform numpy.exp on a very large ndarray, let's say ar, and store the result in ar itself. Can this operation be performed in-place?

Phionna answered 20/12, 2016 at 15:25 Comment(4)
I'm not sure you can do this without temporarily allocating an array. If you could, I don't see how that would work with fast vectorization in numpy.Moisture
what is wrong with ar = np.exp(ar). @AndrasDeak, is that what you meant?Jessalin
@Jessalin I assume OP's point is that if they have 6 GB RAM and 5 GB in ar, they can't allocate np.exp(ar) alongside ar temporarily. And yes, if you can allocate temporarily, it's straightforward to do something like that:)Moisture
@AndrasDeak I see.Jessalin
D
12

You can use the optional outargument of exp:

a = np.array([3.4, 5])
res = np.exp(a, a)
print(res is a)
print(a)

Output:

True
[  29.96410005  148.4131591 ]

exp(x[, out])

Calculate the exponential of all elements in the input array.

Returns

out : ndarray Output array, element-wise exponential of x.

Here all elements of a will be replaced by the result of exp. The return value res is the same as a. No new array is created

Dyke answered 20/12, 2016 at 15:27 Comment(3)
That's probably the most memory-efficient solution possible. I'd still think that there's internal allocation inside np.exp, but it probably doesn't get any better than this.Moisture
Thank you for your answer. Next time I will take a closer look at the docs!Phionna
I don't think there is an internal allocation when out is provided.Cresol
V
5

Mike Mueller's answer is good but please note that if your array is of type int32, int, int64 etc., it will throw a TypeError. Thus, a safe way to do this is to typecast your array to float64 or float32 etc., before doing exp like,

In [12]: b
Out[12]: array([1, 2, 3, 4, 5], dtype=int32)

In [13]: np.exp(b, b)
--------------------------------------------------------------------------
TypeError: ufunc 'exp' output (typecode 'd') could not be coerced to provided 
output parameter (typecode 'i') according to the casting rule ''same_kind''

Type Casting & exp:

# in-place typecasting
In [14]: b = b.astype(np.float64, copy=False)
In [15]: b
Out[15]: array([ 1.,  2.,  3.,  4.,  5.], dtype=float64)

# modifies b in-place
In [16]: np.exp(b, b)
Out[16]: array([   2.718,    7.389,   20.086,   54.598,  148.413], dtype=float64)
Valenba answered 20/12, 2016 at 17:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.