Parfois, il est utile de "cloner" un vecteur ligne ou colonne dans une matrice. Par clonage, j'entends la conversion d'un vecteur de ligne tel que
[1,2,3]
Dans une matrice
[[1,2,3]
[1,2,3]
[1,2,3]
]
ou un vecteur de colonne tel que
[1
2
3
]
dans
[[1,1,1]
[2,2,2]
[3,3,3]
]
En matlab ou en octave, cela se fait assez facilement:
x = [1,2,3]
a = ones(3,1) * x
a =
1 2 3
1 2 3
1 2 3
b = (x') * ones(1,3)
b =
1 1 1
2 2 2
3 3 3
Je veux répéter cela de manière numpy, mais sans succès
In [14]: x = array([1,2,3])
In [14]: ones((3,1)) * x
Out[14]:
array([[ 1., 2., 3.],
[ 1., 2., 3.],
[ 1., 2., 3.]])
# so far so good
In [16]: x.transpose() * ones((1,3))
Out[16]: array([[ 1., 2., 3.]])
# DAMN
# I end up with
In [17]: (ones((3,1)) * x).transpose()
Out[17]:
array([[ 1., 1., 1.],
[ 2., 2., 2.],
[ 3., 3., 3.]])
Pourquoi la première méthode ( In [16]
) ne fonctionnait-elle pas? Existe-t-il un moyen de réaliser cette tâche en python de manière plus élégante?
python
numpy
linear-algebra
Boris Gorelik
la source
la source
repmat
:repmat([1 2 3],3,1)
ourepmat([1 2 3].',1,3)
repmat
.tile_df
lien iciRéponses:
Voici une façon élégante et pythonique de le faire:
le problème avec
[16]
semble être que la transposition n'a aucun effet sur un tableau. vous voulez probablement une matrice à la place:la source
(N,1)
tableau de formes en utilisant.reshape(-1, 1)
)numpy.tile
comme indiqué dans la réponse de pv .Utilisez
numpy.tile
:ou pour répéter des colonnes:
la source
tile
méthode est 19,5 fois plus rapide que la méthode de la réponse actuellement acceptée (en utilisant la méthode de l'opérateur de multiplication).(1, 3)
copie cette colonne plus de trois fois, c'est pourquoi les lignes du résultat contiennent chacune un seul élément distinct.Notez d'abord qu'avec les opérations de diffusion de numpy, il n'est généralement pas nécessaire de dupliquer des lignes et des colonnes. Voir ceci et cela pour les descriptions.
Mais pour ce faire, répéter et nouvel axe sont probablement le meilleur moyen
Cet exemple est pour un vecteur de ligne, mais appliquer cela à un vecteur de colonne est, espérons-le, évident. répéter semble bien épeler cela, mais vous pouvez également le faire par multiplication comme dans votre exemple
la source
np.repeat
vsnp.tile
?Laisser:
Allocations sans frais
Une vue ne prend pas de mémoire supplémentaire. Ainsi, ces déclarations sont instantanées:
Allocation forcée
Si vous voulez forcer le contenu à résider en mémoire:
Les trois méthodes ont à peu près la même vitesse.
Calcul
Les trois méthodes ont à peu près la même vitesse.
Conclusion
Si vous souhaitez répliquer avant un calcul, envisagez d'utiliser l'une des méthodes «d'allocation à coût nul». Vous ne subirez pas la pénalité de performance de "l'allocation forcée".
la source
Je pense que l'utilisation de la diffusion dans numpy est la meilleure et la plus rapide
J'ai fait une comparaison comme suit
environ 15 fois plus rapide en utilisant la diffusion
la source
None
pour faire la même chose.Une solution propre consiste à utiliser la fonction de produit externe de NumPy avec un vecteur de uns:
donne
n
des lignes répétitives. Changez l'ordre des arguments pour obtenir des colonnes répétitives. Pour obtenir un nombre égal de lignes et de colonnes, vous pouvez fairela source
Vous pouvez utiliser
tile générera les répétitions du vecteur
et remodeler lui donnera la forme que vous voulez
la source
Si vous avez un dataframe pandas et que vous souhaitez conserver les dtypes, même les catégoriques, c'est un moyen rapide de le faire:
la source
donne:
la source