web-dev-qa-db-fra.com

Numpy: Divise chaque ligne par un élément vectoriel

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?

95
BFTM

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]])
150
JoshAdel

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

10
IanH

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]])
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.

0
meow

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

0
shantanu pathak