Je souhaite créer une matrice à partir d'une fonction, telle que la (3,3)
matrice C ait des valeurs égales à 1 si l'index de ligne est inférieur à un seuil k donné.
import numpy as np k = 3 C = np.fromfunction(lambda i,j: 1 if i < k else 0, (3,3))
Cependant, ce morceau de code génère une erreur
"La valeur de vérité d'un tableau avec plus d'un élément est ambiguë. Utilisez a.any () ou a.all () "et je ne comprends pas vraiment pourquoi.
3 Réponses :
Comme suggéré par @MarkSetchell, vous devez vectorisez votre fonction:
C array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
et vous obtenez:
k = 3 f = lambda i,j: 1 if i < k else 0 C = np.fromfunction(np.vectorize(f), (3,3))
Il a également suggéré une mise en forme avec 5 rangées pour que vous puissiez voir et vérifier le résultat!
@MarkSetchell Il est vraiment brillant.
Le problème est que np.fromfunction
n'itère pas sur tous les éléments, il ne renvoie que les indices de chaque dimension. Vous pouvez utiliser np.where ()
pour appliquer une condition basée sur ces indices, en choisissant parmi deux alternatives en fonction de la condition:
array([[1, 1, 1], [1, 1, 1], [1, 1, 1], [0, 0, 0], [0, 0, 0]])
ce qui donne: p >
import numpy as np k = 3 np.fromfunction(lambda i, j: np.where(i < k, 1, 0), (5,3))
Cela évite de nommer le lambda sans que les choses deviennent trop lourdes. Sur mon ordinateur portable, cette approche était environ 20 fois plus rapide que np.vectorize()
.
Le code pour fromfunction
est:
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]])
Vous voyez qu'il appelle function
une seule fois - avec tout le tableau de indices
. Ce n'est pas itératif.
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]])
Votre lambda attend des valeurs scalaires i, j
, pas un tableau 3D
lambda i,j: 1 if i < k else 0
Créez un tableau de zéros
c = np.zeros ((3,3))
, puisc [: k,:] = 1
?Cela fonctionnerait, mais je suis intéressé par la nature de cette erreur.
Hein? Sûrement
l = lambda i, j: 1 si i et
C = np.fromfunction (np.vectorize (l), (5,3))
np.fromfunction crée simplement une grille et transmet le tout à votre fonction en un seul appel. Regardez son code.