Je veux découper un tableau NumPy nxn. Je veux extraire une sélection arbitraire de m lignes et colonnes de ce tableau (c'est-à-dire sans aucun motif dans le nombre de lignes / colonnes), ce qui en fait un nouveau tableau mxm. Pour cet exemple, disons que le tableau est 4x4 et que je veux en extraire un tableau 2x2.
Voici notre tableau:
from numpy import *
x = range(16)
x = reshape(x,(4,4))
print x
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
La ligne et les colonnes à supprimer sont les mêmes. Le cas le plus simple est celui où je veux extraire une sous-matrice 2x2 qui se trouve au début ou à la fin, c'est-à-dire:
In [33]: x[0:2,0:2]
Out[33]:
array([[0, 1],
[4, 5]])
In [34]: x[2:,2:]
Out[34]:
array([[10, 11],
[14, 15]])
Mais que faire si je dois supprimer un autre mélange de lignes / colonnes? Que faire si je dois supprimer les première et troisième lignes / lignes, extrayant ainsi la sous [[5,7],[13,15]]
- matrice ? Il peut y avoir n'importe quelle composition de lignes / lignes. J'ai lu quelque part que j'ai juste besoin d'indexer mon tableau à l'aide de tableaux / listes d'indices pour les lignes et les colonnes, mais cela ne semble pas fonctionner:
In [35]: x[[1,3],[1,3]]
Out[35]: array([ 5, 15])
J'ai trouvé un moyen, qui est:
In [61]: x[[1,3]][:,[1,3]]
Out[61]:
array([[ 5, 7],
[13, 15]])
Le premier problème avec ceci est qu'il est à peine lisible, même si je peux vivre avec cela. Si quelqu'un a une meilleure solution, j'aimerais certainement l'entendre.
Une autre chose est que j'ai lu sur un forum que l'indexation de tableaux avec des tableaux oblige NumPy à faire une copie du tableau souhaité, donc lors du traitement avec de grands tableaux, cela pourrait devenir un problème. Pourquoi est-ce ainsi / comment fonctionne ce mécanisme?
x[[[1],[3]],[1,3]]
crée un seul nouveau tableau, tandis quex[[1,3],:][:,[1,3]]
copie deux fois, utilisez donc le premier.Je ne pense pas que ce
x[[1,3]][:,[1,3]]
soit à peine lisible. Si vous voulez être plus clair sur votre intention, vous pouvez faire:Je ne suis pas un expert en tranchage, mais généralement, si vous essayez de découper dans un tableau et que les valeurs sont continues, vous obtenez une vue où la valeur de la foulée est modifiée.
Par exemple, dans vos entrées 33 et 34, bien que vous obteniez un tableau 2x2, la foulée est 4. Ainsi, lorsque vous indexez la ligne suivante, le pointeur se déplace vers la position correcte en mémoire.
De toute évidence, ce mécanisme ne s'intègre pas bien dans le cas d'un tableau d'indices. Par conséquent, numpy devra faire la copie. Après tout, de nombreuses autres fonctions mathématiques matricielles reposent sur la taille, la foulée et l'allocation continue de la mémoire.
la source
Si vous souhaitez ignorer toutes les autres lignes et toutes les autres colonnes, vous pouvez le faire avec un découpage de base:
Cela renvoie une vue, pas une copie de votre tableau.
while
z=x[(1,3),:][:,(1,3)]
utilise une indexation avancée et renvoie donc une copie:Notez que
x
c'est inchangé:Si vous souhaitez sélectionner des lignes et des colonnes arbitraires, vous ne pouvez pas utiliser le découpage de base. Vous devrez utiliser l'indexation avancée, en utilisant quelque chose comme
x[rows,:][:,columns]
, oùrows
etcolumns
sont des séquences. Cela va bien sûr vous donner une copie, pas une vue, de votre tableau d'origine. C'est comme on devrait s'y attendre, car un tableau numpy utilise une mémoire contiguë (avec des foulées constantes), et il n'y aurait aucun moyen de générer une vue avec des lignes et des colonnes arbitraires (car cela nécessiterait des foulées non constantes).la source
Avec numpy, vous pouvez passer une tranche pour chaque composant de l'index - ainsi, votre
x[0:2,0:2]
exemple ci-dessus fonctionne.Si vous voulez simplement sauter des colonnes ou des lignes de manière uniforme, vous pouvez passer des tranches avec trois composants (c'est-à-dire démarrer, arrêter, étape).
Encore une fois, pour votre exemple ci-dessus:
Ce qui est fondamentalement: tranche dans la première dimension, avec début à l'index 1, arrête lorsque l'index est égal ou supérieur à 4, et ajoute 2 à l'index à chaque passage. Idem pour la deuxième dimension. Encore une fois: cela ne fonctionne que pour des étapes constantes.
La syntaxe que vous devez faire quelque chose de très différent en interne - ce qui
x[[1,3]][:,[1,3]]
fait en fait est de créer un nouveau tableau comprenant uniquement les lignes 1 et 3 du tableau d'origine (fait avec lax[[1,3]]
partie), puis de le re-découper - en créant un troisième tableau - y compris seulement colonnes 1 et 3 du tableau précédent.la source
J'ai une question similaire ici: écrire dans le sous-ndarray d'un ndarray de la manière la plus pythonienne. Python 2 .
Suite à la solution de l'article précédent pour votre cas, la solution ressemble à:
Un utilisant ix_:
Lequel est:
la source
Je ne sais pas à quel point c'est efficace, mais vous pouvez utiliser range () pour couper dans les deux axes
la source