J'essaie de convertir un code matlab en python et j'ai été confronté à un code comme:
a.item(x) #python
cela obtient en fait des index de b et fait
a=[1 2 3;4 5 6;7 8 9] b=[1, 4, 8] a(b) //output : ans : 1 4 8
3 Réponses :
Attention: au moment de rédiger cette réponse, l'exemple donné dans la question est faux. a (b)
entraînerait:
import numpy as np a = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]]) b = np.array([0, 3, 7]) c = a[np.unravel_index(b, a.shape, 'F')] print(a) print(b) print(c) [[10 20 30] [40 50 60] [70 80 90]] [0 3 7] [10 20 60]
Le code MATLAB fourni utilise indexation linéaire , qui utilise l'ordre des colonnes principales, alors que le a.item (x)
Python indiqué utilise l'ordre des lignes principales.
La ind2sub
La fonction MATLAB peut convertir des indices linéaires en indices de tableau. Une fonction numpy
similaire est unravel_index
.
Jetons un œil à l'exemple de code suivant. Attention: Python utilise une indexation basée sur 0 alors que MATLAB utilise une indexation basée sur 1.
ans = 1 2 6
Dans une session Octave:
In [75]: np.unravel_index(b, (3,3)) Out[75]: (array([0, 1, 2]), array([0, 0, 1])) In [76]: a[_] # using the Out[75] line as index Out[76]: array([1, 2, 6]) In [77]: a[0,0],a[1,0],a[2,1] # equivalently Out[77]: (1, 2, 6)
Ce n'est pas le genre de comportement que je me souviens avoir dans MATLAB, mais je n'ai pas l'habitude d'utiliser des valeurs d'index supérieures à dimensions. Il s'agit évidemment de sélectionner les éléments dans une matrice aplatie
>> [r,c] = ind2sub([3,3],b) r = 1 1 2 c = 1 2 3 >> a(1,1), a(1,2), a(2,3) ans = 1 ans = 2 ans = 6
En Python / numpy, l'indexation se fait avec []
au lieu de () . Il est également basé sur 0, et non sur 1.
In [67]: a = np.arange(1,10).reshape(3,3,order='F') In [68]: a Out[68]: array([[1, 4, 7], [2, 5, 8], [3, 6, 9]]) In [69]: a.flat[b] Out[69]: array([1, 2, 6])
Pour obtenir les mêmes valeurs dans numpy
, j'ai dû spécifier order F code > lors de l'aplatissement du tableau. De cette façon, il «scanne» les valeurs dans l'ordre majeur de colonne utilisé par MATLAB.
Sans order F
, l'ordre d'analyse par défaut est la ligne principale:
In [61]: a.ravel() Out[61]: array([1, 2, 3, 4, 5, 6, 7, 8, 9]) In [62]: a.ravel()[b] Out[62]: array([1, 4, 8])
Je pourrais également obtenir la commande F lors du remodelage initial de a
:
In [56]: a = np.arange(1,10).reshape(3,3) In [57]: a Out[57]: array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) In [58]: b=[0,3,7] In [59]: a.ravel(order='F')[b] Out[59]: array([1, 2, 6]) In [60]: a.ravel(order='F') Out[60]: array([1, 4, 7, 2, 5, 8, 3, 6, 9])
===
Dans MATLAB / Octave, on peut obtenir les indices 2d avec:
>> reshape(a,1,9) ans = 1 4 7 2 5 8 3 6 9 >> reshape(a,1,9)(b) ans = 1 2 6
Le même démêlage en numpy
(appliqué à la version de la commande F de a
):
>> a=[1 2 3;4 5 6;7 8 9] a = 1 2 3 4 5 6 7 8 9 >> b=[1, 4, 8] b = 1 4 8 >> a(b) ans = 1 2 6
2D
en 1D
b
pour rechercher des données dans a
python
commence à partir de 0
matlab
est 1
, vous devez donc
réduire les indices en b de 1 import numpy as np a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) a = a.flatten() b = np.array([1, 4, 8]) print(a[b-1]) #array([1, 4, 8])
L'indexation linéaire MATLAB utilise l'ordre principal des colonnes, tandis que votre solution utilise l'ordre principal des lignes. Malheureusement, l'exemple donné dans la question est déjà faux sur cette partie.
@HansHirse Que voulez-vous dire par l'exemple donné est faux sur cette partie? Vous pensiez que c'était le même résultat qu'il voulait reproduire en python? pas seulement un exemple
S'il vous plaît voir mon commentaire sur la question: a (b)
renvoie 1 2 6
, et non 1 4 8
comme indiqué par l'interlocuteur. Donc, en fin de compte, il n'est pas clair si l'auteur veut imiter le fonctionnement (correct) de MATLAB (indexation de l'ordre principal des colonnes), ou l'indexation de l'ordre des lignes principales données, ce qui ne serait alors pas la bonne manière MATLAB.
Probablement un double de Comment puis-je comparer deux listes en python et renvoyer les correspondances . Désolé de ne pas savoir comment définir une question comme doublon d'une autre.
@Chunpin Non, ce n'est pas le même problème. De plus,
a (b)
donneet = 1 2 6
.