Supposons que j'ai un tableau numpy:
data = np.array([[1,1,1],[2,2,2],[3,3,3]])
et j'ai un "vecteur:" correspondant
vector = np.array([1,2,3])
Comment puis-je opérer sur data
le long de chaque ligne pour soustraire ou diviser afin que le résultat soit:
sub_result = [[0,0,0], [0,0,0], [0,0,0]]
div_result = [[1,1,1], [1,1,1], [1,1,1]]
En bref: comment effectuer une opération sur chaque ligne d'un tableau 2D avec un tableau 1D de scalaires correspondant à chaque ligne?
Voici. Vous devez juste utiliser None
(ou alternativement np.newaxis
) combiné à la radiodiffusion:
In [6]: data - vector[:,None]
Out[6]:
array([[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
In [7]: data / vector[:,None]
Out[7]:
array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
Comme cela a été mentionné, découper avec None
ou avec np.newaxes
est un excellent moyen de le faire. Une autre alternative consiste à utiliser les transpositions et la diffusion, comme dans
(data.T - vector).T
et
(data.T / vector).T
Pour les tableaux de dimension supérieure, vous pouvez utiliser la méthode swapaxes
des tableaux NumPy ou la fonction NumPy rollaxis
. Il y a vraiment beaucoup de façons de faire cela.
Pour une explication plus complète de la radiodiffusion, voir http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
La solution de JoshAdel utilise np.newaxis pour ajouter une dimension. Une alternative consiste à utiliser reshape () pour aligner les dimensions en vue de la diffusion .
data = np.array([[1,1,1],[2,2,2],[3,3,3]])
vector = np.array([1,2,3])
data
# array([[1, 1, 1],
# [2, 2, 2],
# [3, 3, 3]])
vector
# array([1, 2, 3])
data.shape
# (3, 3)
vector.shape
# (3,)
data / vector.reshape((3,1))
# array([[1, 1, 1],
# [1, 1, 1],
# [1, 1, 1]])
Effectuer reshape () permet aux dimensions de s’aligner pour la diffusion:
data: 3 x 3
vector: 3
vector reshaped: 3 x 1
Notez que data/vector
ça va, mais ça ne vous donne pas la réponse que vous voulez. Il divise chaque colonne de array
(au lieu de chaque rangée ) par chaque élément correspondant de vector
. C'est ce que vous obtiendriez si vous reformuliez explicitement vector
pour qu'il soit 1x3
au lieu de 3x1
.
data / vector
# array([[1, 0, 0],
# [2, 1, 0],
# [3, 1, 1]])
data / vector.reshape((1,3))
# array([[1, 0, 0],
# [2, 1, 0],
# [3, 1, 1]])
Ajoutant à la réponse de stackoverflowuser2010, dans le cas général, vous pouvez simplement utiliser
data = np.array([[1,1,1],[2,2,2],[3,3,3]])
vector = np.array([1,2,3])
data / vector.reshape(-1,1)
Cela transformera votre vecteur en un column matrix/vector
. Vous permettant d'effectuer les opérations élément par élément à votre guise. Du moins pour moi, c’est la façon la plus intuitive de procéder et puisque (dans la plupart des cas) numpy utilisera simplement une vue de la même mémoire interne pour la refaçonner, c’est efficace aussi.
Façon pythonique de le faire est ...
np.divide(data,vector)
Cela prend en charge le remodelage et les résultats sont également au format virgule flottante. Dans les autres réponses, les résultats sont au format entier arrondi.
# NOTE: Le nombre de colonnes dans les données et les vecteurs doit correspondre