web-dev-qa-db-fra.com

Quel est l'équivalent du repmat de MATLAB dans NumPy

Je voudrais exécuter l'équivalent du code MATLAB suivant en utilisant NumPy: repmat([1; 1], [1 1 1]). Comment pourrais-je accomplir ceci?

85
vernomcrp

Voici un bien meilleur (officiel) NumPy pour les utilisateurs de Matlab link - J'ai bien peur que le mathesaurus ne soit plus à jour.

L'équivalent numérique de repmat(a, m, n) est tile(a, (m, n))

Cela fonctionne avec plusieurs dimensions et donne un résultat similaire à matlab. (Numpy donne un tableau de sortie 3D comme on peut s'y attendre - matlab, pour une raison quelconque, donne une sortie 2D - mais le contenu est le même).

Matlab:

>> repmat([1;1],[1,1,1])

ans =
     1
     1

Python:

In [46]: a = np.array([[1],[1]])
In [47]: np.tile(a, [1,1,1])
Out[47]: 
array([[[1],
        [1]]])
88
robince

Notez que certaines des raisons pour lesquelles vous auriez besoin d'utiliser le repmat de MATLAB sont gérées par le mécanisme broadcast de NumPy, qui vous permet de faire différents types de maths avec des tableaux de forme similaire. Donc, si vous aviez un tableau de 1600x1400x3 représentant une image à 3 couleurs, vous pourriez (élément par élément) le multiplier par [1.0 0.25 0.25] pour réduire la quantité de vert et de bleu de chaque pixel. Voir le lien ci-dessus pour plus d'informations.

16
kwatford

Voir NumPy pour les utilisateurs de Matlab .

Matlab:

repmat(a, 2, 3)

Numpy:

numpy.kron(numpy.ones((2,3)), a)
9
rcs

Connaître à la fois tile et repeat.

x = numpy.arange(5)
print numpy.tile(x, 2)
print x.repeat(2)
5
Steve Tjoa

C’est ainsi que j’ai bien compris la situation. Heureux d'être corrigé et espère que cela aide.

Supposons que vous ayez une matriceMde 2x3 éléments. Cela a évidemment deux dimensions.


Je ne pouvais voir aucune différence entre Matlab et Python lorsque je demandais de manipuler la matrice d'entrée le long des dimensions déjà présentes dans la matrice. Ainsi les deux commandes

repmat(M,m,n) % matlab

np.tile(M,(m,n)) # python

sont vraiment équivalentes pour une matrice de rang 2 (deux dimensions). 


La question devient contre-intuitive lorsque vous demandez la répétition/mosaïque sur plus de dimensions que la matrice d'entrée. Pour revenir à la matrice M de rang deux et de forme 2x3, il suffit de regarder ce qu’il advient de la taille/forme de la matrice de sortie. Disons que la séquence de manipulation est maintenant 1,1,2.

À Matlab

> size(repmat(M,1,1,2))
ans =

    2   3   2

il a copié les deux premières dimensions (lignes et colonnes) de la matrice d'entrée et l'a répété une fois dans une nouvelle troisième dimension (c'est-à-dire copié deux fois). Fidèle au nom repmat pour la matrice de répétition. 

En python

>>> np.tile(M,(1,1,2)).shape
(1, 2, 6)

il a appliqué une procédure différente puisque, je suppose, la séquence (1,1,2) est lue différemment de celle de Matlab. Le nombre de copies dans le sens des colonnes, des lignes et des dimensions hors plan est lu de droite à gauche. L'objet résultant a une forme différente de Matlab. On ne peut plus affirmer que repmat et tile sont des instructions équivalentes.


Pour que tile se comporte comme repmat, en Python, vous devez vous assurer que la matrice en entrée a autant de dimensions que d'éléments dans la séquence. Cela se fait, par exemple, par un peu de préconditionnement et la création d’un objet associéN

N = M[:,:,np.newaxis]

Ensuite, du côté entrée, on a N.shape = (2,3,1) plutôt que M.shape = (2,3) et du côté sortie

>>> np.tile(N,(1,1,2)).shape
(2, 3, 2)

ce qui était la réponse de size(repmat(M,1,1,2)). Je suppose que c'est parce que nous avons guidé Python pour ajouter la troisième dimension à droite de (2,3) plutôt qu'à sa gauche, de sorte que Python calcule la séquence (1,1,2) comme elle était prévue dans Matlab. façon de le lire.

L'élément dans [:,:,0] dans la réponse Python pourNcontiendra les mêmes valeurs que l'élément (:,:,1) et la réponse Matlab pourM.


Enfin, je ne semble pas pouvoir trouver d’équivalent pour repmat lorsqu’on utilise le produit Kronecker sur

>>> np.kron(np.ones((1,1,2)),M).shape
(1, 2, 6)

à moins que je ne conditionne alorsMenNcomme ci-dessus. Je dirais donc que la façon la plus générale de passer à autre chose est d'utiliser les méthodes de np.newaxis.


Le jeu devient plus délicat quand on considère une matriceLde rang 3 (trois dimensions) et le cas simple où aucune nouvelle dimension n’a été ajoutée dans la matrice de sortie. Ces deux instructions apparemment équivalentes ne produiront pas les mêmes résultats

repmat(L,p,q,r) % matlab

np.tile(L,(p,q,r)) # python

parce que les directions de rangée, de colonne et hors du plan sont (p, q, r) dans Matlab et (q, r, p) en Python, qui n'était pas visible avec les tableaux de rang 2. Là, il faut être prudent et obtenir les mêmes résultats avec les deux langues nécessiterait plus de préconditionnement. 


Je suis conscient que ce raisonnement peut ne pas être général, mais je ne pourrais le comprendre que si loin. Espérons que cela invite les autres boursiers à le soumettre à une épreuve plus difficile.

4
XavierStuvw

numpy.matlib a une fonction repmat avec une interface similaire à la fonction matlab

from numpy.matlib import repmat
repmat( np.array([[1],[1]]) , 1, 1)
0
e-malito
import numpy as np

np.repeat(['a','b'], [2,5])
>>> array(['a', 'a', 'b', 'b', 'b', 'b', 'b'], dtype='<U1')

np.repeat([1,2], [2,5])
>>> array([1, 1, 2, 2, 2, 2, 2])

np.repeat(np.array([1,2]), [3]).reshape(2,3)
>>> array([[1, 1, 1],
           [2, 2, 2]])

np.repeat(np.array([1,2]), [2,4]).reshape(3,2)
>>> array([[1, 1],
           [2, 2],
           [2, 2]])

np.repeat(np.matrix('1 2; 3 4'), [2]).reshape(4,2)
>>> matrix([[1, 1],
            [2, 2],
            [3, 3],
            [4, 4]])
0
Hamidreza