Putting Lambda In Numpy `np.fromfunction()` Causes Typeerror
Solution 1:
Look at the error:
In [171]: np.fromfunction(f, ds.shape)
---------------------------------------------------------------------------
TypeError Traceback (most recent calllast)
<ipython-input-171-1a3ed1ade41a>in<module>----> 1 np.fromfunction(f, ds.shape)/usr/local/lib/python3.6/dist-packages/numpy/core/numeric.py in fromfunction(function, shape, **kwargs)
2026 dtype = kwargs.pop('dtype', float)
2027 args = indices(shape, dtype=dtype)
->2028returnfunction(*args, **kwargs)
20292030
TypeError: <lambda>() takes 1 positional argument but 2 were given
fromfunction is a small Python function; there's no compiled magic.
Based on the shape you give, it generates indices.
In [172]: np.indices(ds.shape)
Out[172]:
array([[[0, 0, 0],
[1, 1, 1],
[2, 2, 2]],
[[0, 1, 2],
[0, 1, 2],
[0, 1, 2]]])
That's a (2,3,3) array. The 2 from the 2 element shape, and the (3,3) from the shape itself. This is similar to what np.meshgrid and np.mgrid produce. Just indexing arrays.
It then passes that array to your function, with *args unpacking.
function(*args, **kwargs)
In [174]: f(Out[172][0], Out[172][1])
---------------------------------------------------------------------------
TypeError Traceback (most recent calllast)
<ipython-input-174-40469f1ab449>in<module>----> 1 f(Out[172][0], Out[172][1])
TypeError: <lambda>() takes 1 positional argument but 2 were given
That's all it does - generate a n-d grid, and pass it as n arguments to your function.
===
Note also that you passed ds.shape to fromfunction, but not ds itself. You could just as well written np.fromfunction(f,(3,3)).
What do you want your lambda to do with ds? Clearly fromfunction isn't doing it for you.
===
With this f, the only that fromfunction can do is give it a arange:
In [176]: np.fromfunction(f, (10,))
Out[176]: 45.0
In [177]: f(np.arange(10))
Out[177]: 45.0===
In the linked SO the lambda takes 2 arguments, lambda x,y:
np.fromfunction(lambda x,y: np.abs(target[0]-x) + np.abs(target[1]-y), ds.shape)
In that SO, both the question and answer, the ds array is just the source of the shape, Target is (0,1), the largest element of ds.
Effectively, the fromfunction in the linked answer is just doing:
In [180]: f1 = lambda x,y: np.abs(0-x) + np.abs(1-y)
In [181]: f1(Out[172][0], Out[172][1])
Out[181]:
array([[1, 0, 1],
[2, 1, 2],
[3, 2, 3]])
In [182]: np.abs(0-Out[172][0]) + np.abs(1-Out[172][1])
Out[182]:
array([[1, 0, 1],
[2, 1, 2],
[3, 2, 3]])
In [183]: np.abs(np.array([0,1])[:,None,None]-Out[172]).sum(axis=0)
Out[183]:
array([[1, 0, 1],
[2, 1, 2],
[3, 2, 3]])
In [184]: np.abs(0-np.arange(3))[:,None] + np.abs(1-np.arange(3))
Out[184]:
array([[1, 0, 1],
[2, 1, 2],
[3, 2, 3]])
Solution 2:
As you are using a 2 dimensional array, your function needs to take 2 inputs.
The docs of np.fromfunction()https://docs.scipy.org/doc/numpy/reference/generated/numpy.fromfunction.html say "Construct an array by executing a function over each coordinate."
So it will pass the coordinates of each element of the array ((0,0), then (0,1) ... etc) to construct an array. Is this really what you are trying to do?
You could change the lambda to something like this, but it really depends on what you are trying to do!
f = lambda x, y: np.linalg.norm([x,y],1)
Post a Comment for "Putting Lambda In Numpy `np.fromfunction()` Causes Typeerror"