Constant lambda expressions, shape of return data

2019-08-28 23:52发布

问题:

A list of lambda expressions given to me (by Sympy's lambdify), some explicitly depending on a variable x, some constant. I would like to evaluate those consistently with Numpy arrays.

When evaluating a lambda expression, e.g., lambda x: 1.0 + x**2, with a Numpy array x, the result will have the same shape as the array. If the expression happens to not explicitly contain x though, e.g., g = lambda x: 1.0, only a scalar is returned.

import numpy

f = [lambda x: 1.0 + x**2, lambda x: 1.0]

X = numpy.array([1, 2, 3])

print(f[0](X))
print(f[1](X))

returns

[  2.   5.  10.]
1.0

Is there a way to get the shapes of the output arguments consistent?

回答1:

You could use ones_like:

>>> X = numpy.array([1, 2, 3])
>>> def g(x): return numpy.ones_like(x)
>>> g(X)
array([1, 1, 1])

Note that this returns integers, not floats, because that was the input dtype; you could specify dtype=float or multiply by 1.0 if you prefer to always get floats out.

PS: It's a little odd to use a lambda and then immediately give it a name. It's like wearing a mask but handing out business cards.

PPS: back before ones_like I tended to use x*0+1 when I wanted something appropriately shaped.



回答2:

I don't see the problem, just do:

import numpy as np

X = np.array([1, 2, 3])

f = lambda x: 1.0 + x**2
print(f(X))

g = lambda x: np.ones(shape=(len(X),))
print(g(X))

Which prints:

[  2.   5.  10.]
[ 1.  1.  1.]

Notice that using np.ones(shape=(len(X),)) is the same that using np.ones_like(X)



回答3:

Use ones_like:

g = lambda x: np.ones_like(x) * 1.0

There's also this slightly hackier solution:

g = lambda x: 1.0 + (x*0)


回答4:

You seem to want an array of ones:

>>> import numpy
>>> numpy.ones(3)
array([ 1.,  1.,  1.])

If you want to set scalars, it's easy to do so

g = lambda x: numpy.ones(shape=x.shape) * 2

g(X)

returns

array([ 2.,  2.,  2.])

So for an arbitrary array:

g = lambda x: numpy.ones(shape=x.shape) * 1

n = numpy.array([1,2,3,4,5])

g(n) is

array([ 1.,  1.,  1.,  1.,  1.])