web-dev-qa-db-fra.com

Python: Différenciation entre les vecteurs de lignes et de colonnes

Existe-t-il un bon moyen de différencier les vecteurs de lignes et de colonnes en python? Jusqu'ici, j'utilise numpy et scipy et ce que je vois jusqu'ici est que si je devais donner à un vecteur un vecteur, disons

from numpy import *
Vector = array([1,2,3])

ils ne seraient pas en mesure de dire météo, je veux dire une ligne ou un vecteur de colonne. En outre:

array([1,2,3]) == array([1,2,3]).transpose()
True

Ce qui dans le "monde réel" est tout simplement faux ... Je me rends compte que la plupart des fonctions sur les vecteurs des modules mentionnés n’ont pas besoin de différenciation. Par exemple, outer(a,b) ou a.dot(b) mais je voudrais faire la différence pour ma propre commodité.

47
MarcinKonowalczyk

Vous pouvez rendre la distinction explicite en ajoutant une autre dimension au tableau.

>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
>>> a.transpose()
array([1, 2, 3])
>>> a.dot(a.transpose())
14

Forcez-le maintenant à être un vecteur colonne:

>>> a.shape = (3,1)
>>> a
array([[1],
       [2],
       [3]])
>>> a.transpose()
array([[1, 2, 3]])
>>> a.dot(a.transpose())
array([[1, 2, 3],
       [2, 4, 6],
       [3, 6, 9]])

Une autre option consiste à utiliser np.newaxis lorsque vous souhaitez faire la distinction:

>>> a = np.array([1, 2, 3])
>>> a
array([1, 2, 3])
>>> a[:, np.newaxis]
array([[1],
       [2],
       [3]])
>>> a[np.newaxis, :]
array([[1, 2, 3]])
54
bogatron

Utilisez le double [] lorsque vous écrivez vos vecteurs.

Ensuite, si vous voulez un vecteur ligne:

row_vector = array([[1, 2, 3]])    # shape (1, 3)

Ou si vous voulez un vecteur de colonne:

col_vector = array([[1, 2, 3]]).T  # shape (3, 1)
17
davidA

Je pense que vous pouvez utiliser l'option ndmin de numpy.array. Le garder à 2 dit que ce sera un (4,1) et que transposer sera (1,4). 

>>> a = np.array([12, 3, 4, 5], ndmin=2)
>>> print a.shape
>>> (1,4)
>>> print a.T.shape
>>> (4,1)
5
abhra

Si vous voulez une distinction pour ce cas, je vous recommanderais d'utiliser plutôt une matrix, où:

matrix([1,2,3]) == matrix([1,2,3]).transpose()

donne:

matrix([[ True, False, False],
        [False,  True, False],
        [False, False,  True]], dtype=bool)

Vous pouvez également utiliser une ndarray en ajoutant explicitement une deuxième dimension:

array([1,2,3])[None,:]
#array([[1, 2, 3]])

et: 

array([1,2,3])[:,None]
#array([[1],
#       [2],
#       [3]])
4

Le vecteur que vous créez n'est ni ligne ni colonne . En réalité, il n'a qu'une seule dimension. Vous pouvez vérifier cela en

  • vérification du nombre de dimensions myvector.ndim qui est 1
  • vérifier le myvector.shape, qui est (3,) (un tuple avec un seul élément). Pour une ligne, le vecteur doit être (1, 3), et pour une colonne (3, 1)

Deux façons de gérer cela

  • créer un vecteur ligne/colonne actual
  • reshape votre actuel

Vous pouvez explicitement créer une ligne ou une colonne

row = np.array([    # one row with 3 elements
   [1, 2, 3]
]
column = np.array([  # 3 rows, with 1 element each
    [1],
    [2],
    [3]
])

ou, avec un raccourci

row = np.r_['r', [1,2,3]]     # shape: (1, 3)
column = np.r_['c', [1,2,3]]  # shape: (3,1)

Vous pouvez également le remodeler en (1, n) pour la ligne ou en (n, 1) pour la colonne.

row = my_vector.reshape(1, -1)
column = my_vector.reshape(-1, 1)

où le -1 trouve automatiquement la valeur de n.

3
blue_note

Il semble que Numpy de Python ne le distingue pas à moins que vous ne l'utilisiez dans son contexte:

"Vous pouvez avoir des vecteurs standard ou des vecteurs ligne/colonne si vous le souhaitez."

":) Vous pouvez traiter les tableaux de rang 1 comme des vecteurs de ligne ou de colonne. Dot (A, v) traite v comme un vecteur colonne, tandis que point (v, A) traite v comme un vecteur ligne. tapez beaucoup de transposées ".

Aussi, spécifique à votre code: "Transposer un tableau de rang 1 ne fait rien." Source: http://wiki.scipy.org/NumPy_for_Matlab_Users

2
so13eit

Si je veux un tableau 1x3 ou 3x1:

import numpy as np
row_arr = np.array([1,2,3]).reshape((1,3))
col_arr = np.array([1,2,3]).reshape((3,1)))

Vérifie ton travail:

row_arr.shape  #returns (1,3)
col_arr.shape  #returns (3,1)

J'ai trouvé que beaucoup de réponses ici sont utiles, mais beaucoup trop compliquées pour moi. En pratique, je reviens à shape et reshape et le code est lisible: très simple et explicite.

2
neuronet

Vous pouvez stocker les éléments du tableau dans une ligne ou une colonne comme suit:

>>> a = np.array([1, 2, 3])[:, None] # stores in rows
>>> a
array([[1],
       [2],
       [3]])

>>> b = np.array([1, 2, 3])[None, :] # stores in columns
>>> b
array([[1, 2, 3]])
1
Mehran Yarah

Voici un autre moyen intuitif. Supposons que nous ayons:

>>> a = np.array([1, 3, 4])
>>> a
array([1, 3, 4])

Tout d'abord, nous créons un tableau 2D avec comme seule ligne:

>>> a = np.array([a])
>>> a
array([[1, 3, 4]])

Ensuite, nous pouvons le transposer:

>>> a.T
array([[1],
       [3],
       [4]])
0
Evgeni Sergeev

Quand j'ai essayé de calculer w^T * x en utilisant numpy, c'était aussi très déroutant pour moi. En fait, je ne pouvais pas l'implémenter moi-même. Il s’agit donc d’un des rares pièges dans NumPy que nous devons connaître.

En ce qui concerne 1D array, il y a aucune distinction entre un vecteur ligne et un vecteur colonne. Ils sont exactement les mêmes.

Regardez les exemples suivants, où nous obtenons le même résultat dans tous les cas, ce qui n’est pas vrai en algèbre linéaire (sens théorique de):

In [37]: w
Out[37]: array([0, 1, 2, 3, 4])

In [38]: x
Out[38]: array([1, 2, 3, 4, 5])

In [39]: np.dot(w, x)
Out[39]: 40

In [40]: np.dot(w.transpose(), x)
Out[40]: 40

In [41]: np.dot(w.transpose(), x.transpose())
Out[41]: 40

In [42]: np.dot(w, x.transpose())
Out[42]: 40

Avec cette information, essayons maintenant de calculer la longueur au carré du vecteur |w|^2.

Pour cela, nous devons transformer w en tableau 2D.

In [51]: wt = w[:, np.newaxis]

In [52]: wt
Out[52]: 
array([[0],
       [1],
       [2],
       [3],
       [4]])

Calculons maintenant la longueur au carré (ou la magnitude au carré) du vecteur w:

In [53]: np.dot(w, wt)
Out[53]: array([30])

Notez que nous avons utilisé w, wt au lieu de wt, w (comme dans l'algèbre linéaire théorique) en raison de l'inadéquation de forme avec l'utilisation de np.dot (wt, w). Donc, nous avons la longueur au carré du vecteur en tant que [30]. Peut-être que c’est l’un des moyens de distinguer (l’interprétation de numpy) des vecteurs ligne et colonne?

Et finalement, ai-je mentionné que j'avais trouvé le moyen d'implémenter w^T * x? Oui je l'ai fait :

In [58]: wt
Out[58]: 
array([[0],
       [1],
       [2],
       [3],
       [4]])

In [59]: x
Out[59]: array([1, 2, 3, 4, 5])

In [60]: np.dot(x, wt)
Out[60]: array([40])

Ainsi, dans NumPy, l'ordre des opérandes est inversé, comme indiqué ci-dessus, contrairement à ce que nous avons étudié en algèbre linéaire théorique.


P.S.: potentielles pièges en numpy

0
kmario23

L'excellente bibliothèque Pandas ajoute des fonctionnalités à numpy qui rendent ce type d'opérations plus intuitif, aussi bien pour vous. Par exemple:

import numpy as np
import pandas as pd

# column
df = pd.DataFrame([1,2,3])

# row
df2 = pd.DataFrame([[1,2,3]])

Vous pouvez même définir un DataFrame et créer un tableau croisé dynamique semblable à un tableur .

0
cms_mgr