使用numpy的np.fromfunction评估Python lambda函数

3

假设A1和A2是形状相同的numpy数组,例如((d1,d2))。我想要从中构建一个((d1,d1))的数组,其[i,j]元素是对元组A1[i],A2[j]应用函数后得到的结果。我使用np.fromfunction函数来实现:

f=lambda i,j: np.inner(A1[i],A2[j])
A=np.fromfunction(f, shape=(d1, d1)) 

(如Fastest way to initialize numpy array with values given by function中建议的)

然而我得到了错误“'IndexError:用作索引的数组必须是整数(或布尔)类型”。这很奇怪,因为将lambda函数更改为例如

 f=lambda i,j: i*j

运行正常!似乎在lambda函数中调用另一个函数会导致问题。

np.fromfunction
< p>(np.inner仅是一个示例,我希望能够用其他类似的函数来替换它)。

(np.inner只是一个例子,我希望能够用其他相似的函数来代替它。)
1个回答

7
为了调试这种情况,将f变成一个适当的函数并添加打印语句以查看ij的值:
import numpy as np
np.random.seed(2015)
d1, d2 = 5, 3
A1 = np.random.random((d1,d2))
A2 = np.random.random((d1,d2))
def f(i, j):
    print(i, j)
    return np.inner(A1[i],A2[j])
A = np.fromfunction(f, shape=(d1, d1)) 

你会看到(i, j)等于:
(array([[ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.,  3.],
       [ 4.,  4.,  4.,  4.,  4.]]), array([[ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.],
       [ 0.,  1.,  2.,  3.,  4.]]))

啊哈。问题在于这些数组的值是浮点型。正如错误信息所述,索引必须是整数或布尔类型。

仔细查阅np.fromfunction的文档字符串会发现它有第三个参数dtype,用于控制坐标数组的数据类型:

Parameters
dtype : data-type, optional
    Data-type of the coordinate arrays passed to `function`.
    By default, `dtype` is float.

因此,解决方案是在调用np.fromfunction时添加dtype=int:
A = np.fromfunction(f, shape=(d1, d1), dtype=int) 

抱歉,我仍然困惑于使用“i*j”作为函数时,会得到整数数组“(i,j)”,而使用np.inner则会得到您所写的内容?难道“np.fromfunction”不应该只将“f”应用于所有索引对“(i,j)”的组合(在0和d1之间)吗? - fact
1
我认为np.fromfunction不是这个目的的正确函数。你看一下索引ij长什么样子。它们是多余的--没有必要使用i,jf--因为整个计算可以用np.inner(A1,A2)完成。 - unutbu
1
关于:“'np.fromfunction'不应该只对所有元组'(i,j)'应用'f'吗?” 不,这不是np.fromfunction的作用。在NumPy中没有这样的函数,因为对于大型数组,为每个元组调用Python函数f会非常慢。为了有效地利用NumPy,通常希望用最少的函数调用表达计算,并将最大的数组传递给这些函数。这将大部分工作转移到NumPy的快速底层C/Fortran函数上,并尽量少依赖较慢的Python代码。 - unutbu
1
不要尝试逐个元素地表达计算(就像在C语言中一样)。相反,尝试找到能够在整个数组上操作并实现相同结果的NumPy函数。 - unutbu
是的,谢谢!我不知道这个。我刚刚对比了np.inner(A1,A2)和使用A[i,j]=np.inner(A1[i],A2[j]) 进行指标循环,你的解决方案快得多! - fact

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接