python - 将 lambda 放入 NumPy `np.fromfunction()` 会导致 TypeError
问题描述
我试图理解 NumPy np.fromfunction()
。
以下一段代码是从这篇文章中提取的。
dist = np.array([ 1, -1])
f = lambda x: np.linalg.norm(x, 1)
f(dist)
输出
2.0
正如预期的那样。
当我把它们放在一起使用 np.linalg.norm() 里面 np.fromfunction()
ds = np.array([[1, 2, 1],
[1, 1, 0],
[0, 1, 1]])
np.fromfunction(f, ds.shape)
出现错误。
> TypeError Traceback (most recent call
last) <ipython-input-6-f5d65a6d95c4> in <module>()
2 [1, 1, 0],
3 [0, 1, 1]])
----> 4 np.fromfunction(f, ds.shape)
~/anaconda3/envs/tf11/lib/python3.6/site-packages/numpy/core/numeric.py
in fromfunction(function, shape, **kwargs)
2026 dtype = kwargs.pop('dtype', float)
2027 args = indices(shape, dtype=dtype)
-> 2028 return function(*args, **kwargs)
2029
2030
TypeError: <lambda>() takes 1 positional argument but 2 were given
是否可以在 np.fromfunction() 中放置一个 lambda 函数(可能是另一个 lambda 函数)来完成这项工作(获取一个距离数组)?
解决方案
看看错误:
In [171]: np.fromfunction(f, ds.shape)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<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)
-> 2028 return function(*args, **kwargs)
2029
2030
TypeError: <lambda>() takes 1 positional argument but 2 were given
fromfunction
是一个小的 Python 函数;没有编译的魔法。
根据您给出的形状,它会生成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]]])
那是一个 (2,3,3) 数组。2 元素形状中的 2 和形状本身的 (3,3) 。这类似于什么np.meshgrid
和np.mgrid
产生。只是索引数组。
然后它通过*args
解包将该数组传递给您的函数。
function(*args, **kwargs)
In [174]: f(Out[172][0], Out[172][1])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-174-40469f1ab449> in <module>
----> 1 f(Out[172][0], Out[172][1])
TypeError: <lambda>() takes 1 positional argument but 2 were given
这就是它所做的一切 - 生成一个 nd 网格,并将其作为 n 个参数传递给您的函数。
===
另请注意,您传递ds.shape
给fromfunction
,而不是ds
自身。你也可以这样写np.fromfunction(f,(3,3))
。
你要你lambda
做ds
什么?显然fromfunction
不是为你做的。
===
有了这个f
,唯一fromfunction
能做的就是给它一个arange
:
In [176]: np.fromfunction(f, (10,))
Out[176]: 45.0
In [177]: f(np.arange(10))
Out[177]: 45.0
===
在链接的 SO 中,lambda 有 2 个参数,lambda x,y
:
np.fromfunction(lambda x,y: np.abs(target[0]-x) + np.abs(target[1]-y), ds.shape)
在那个 SO 中,无论是问题还是答案,ds
数组只是形状的来源,目标是 (0,1),是 的最大元素ds
。
实际上,fromfunction
链接答案中的只是在做:
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]])
推荐阅读
- hyperledger-fabric - Fabric-ca-server 启动时的关联定义(命令行选项或环境变量)
- ruby-on-rails - Puma Web 服务器积压行为
- outlook - 如何在 Outlook 中阻止传入的电子邮件
- excel - 文本到列宏故障
- ruby - 如何更新键在 ruby 中多次出现的单个哈希值?
- excel - Do While 循环运行时错误 1004 在第二次通过
- jquery - 如何在锚标记的href值中附加当前窗口位置
- ios - 线程 1:在获取 TableView 的可重用单元格时发出 SIGABRT 信号
- java - 从弹出菜单中捕获鼠标 XY 位置
- flutter - 在 ListView.builder 上多次使用相同的索引