从函数创建矩阵

时间:2019-04-26 09:50:37

标签: python numpy

我想从一个函数创建一个矩阵,如果行索引小于给定的阈值k,则(3,3)矩阵C的值等于1。

import numpy as np

k = 3
C = np.fromfunction(lambda i,j: 1 if i < k else 0, (3,3))

但是,这段代码会引发错误

  

”具有多个元素的数组的真值是不明确的。   使用a.any()或a.all()”,我真的不明白为什么。

3 个答案:

答案 0 :(得分:2)

fromfunction的代码是:

dtype = kwargs.pop('dtype', float)
args = indices(shape, dtype=dtype)
return function(*args, **kwargs)

您看到它仅用整个function数组调用一次indices。它不是迭代的。

In [672]: idx = np.indices((3,3))                                                    
In [673]: idx                                                                        
Out[673]: 
array([[[0, 0, 0],
        [1, 1, 1],
        [2, 2, 2]],

       [[0, 1, 2],
        [0, 1, 2],
        [0, 1, 2]]])

您的lambda期望标量i,j的值,而不是3d数组

 lambda i,j: 1 if i < k else 0

idx<3是一个3d布尔数组。在if上下文中使用该错误时会出现错误。

如果要将标量函数应用于一组数组,则

np.vectorizenp.frompyfunc更好:

In [677]: np.vectorize(lambda i,j: 1 if i < 2 else 0)(idx[0],idx[1])                 
Out[677]: 
array([[1, 1, 1],
       [1, 1, 1],
       [0, 0, 0]])

但是,它并没有比更直接的迭代方法快,而且也没有比对整个数组进行操作的函数慢。

许多全阵列方法之一:

In [680]: np.where(np.arange(3)[:,None]<2, np.ones((3,3),int), np.zeros((3,3),int))  
Out[680]: 
array([[1, 1, 1],
       [1, 1, 1],
       [0, 0, 0]])

答案 1 :(得分:1)

如@MarkSetchell所建议,您需要vectorize您的功能:

k = 3
f = lambda i,j: 1 if i < k else 0

C = np.fromfunction(np.vectorize(f), (3,3))

您会得到:

C
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

答案 2 :(得分:1)

问题在于<!-- where myEditor is the name of the form control in your FormGroup --> <my-component formControlName="myEditor"></my-component> 不会遍历所有元素,它仅返回每个维中的索引。您可以使用np.fromfunction来基于这些索引应用条件,并根据条件从两种选择中进行选择:

np.where()

给出:

import numpy as np

k = 3
np.fromfunction(lambda i, j: np.where(i < k, 1, 0), (5,3))

这避免了命名lambda而不会使事情变得太笨拙。在我的笔记本电脑上,这种方法比array([[1, 1, 1], [1, 1, 1], [1, 1, 1], [0, 0, 0], [0, 0, 0]]) 快20倍。