Vue sur un tableau numpy?

90

J'ai un numpytableau 2D . Existe-t-il un moyen de créer une vue dessus qui inclurait les premières klignes et toutes les colonnes?

Le but est d'éviter de copier les données sous-jacentes (le tableau est si grand qu'il n'est pas possible de faire des copies partielles.)

NPE
la source

Réponses:

226

Bien sûr, indexez-le comme vous le feriez normalement. Par exemple, y = x[:k, :] cela retournera une vue dans le tableau d'origine. Aucune donnée ne sera copiée et toutes les mises à jour effectuées sur yseront reflétées dans xet vice versa.


Éditer:

Je travaille généralement avec des matrices 3D> 10 Go d'uint8, donc je m'inquiète beaucoup de cela ... Numpy peut être très efficace dans la gestion de la mémoire si vous gardez quelques choses à l'esprit. Voici quelques conseils pour éviter de faire des copies de tableaux en mémoire:

Utilisez +=, -=, *=, etc pour éviter de faire une copie du tableau. Par exemple x += 10, modifiera le tableau en place, tandis que x = x + 10fera une copie et le modifiera. (aussi, jetez un œil à numexpr )

Si vous souhaitez faire une copie avec x = x + 10, sachez que x = x + 10.0cela entraînera xautomatiquement une conversion ascendante vers un tableau à virgule flottante, si ce n'était pas déjà le cas. Toutefois, x += 10.0xest un tableau d'entiers, le cast sera 10.0vers le bas en un entier de la même précision que le tableau.

De plus, de nombreuses fonctions numpy prennent un outparamètre, vous pouvez donc faire des choses comme np.abs(x, x)prendre la valeur absolue de xin-place.


En guise de deuxième modification, voici quelques conseils supplémentaires sur les vues par rapport aux copies avec des tableaux numpy:

Contrairement aux listes python, y = x[:]ne renvoie pas de copie, il renvoie une vue. Si vous voulez une copie (qui, bien sûr, doublera la quantité de mémoire que vous utilisez) utilisey = x.copy()

Vous entendrez souvent parler d '«indexation sophistiquée» des tableaux numpy. Utiliser une liste (ou un tableau d'entiers) comme index est une "indexation sophistiquée". Cela peut être très utile, mais copie les données.

À titre d'exemple: y = x[[0, 1, 2], :]renvoie une copie, tandis y = x[:3,:]que renvoie une vue.

Même une indexation vraiment folle comme l'indexation x[4:100:5, :-10:-1, None]"normale" et retournera une vue, cependant, n'ayez donc pas peur d'utiliser toutes sortes d'astuces de découpage sur de grands tableaux.

x.astype(<dtype>)renverra une copie des données en tant que nouveau type, tandis que x.view(<dtype>)renverra une vue.

Soyez prudent avec cela, cependant ... C'est extrêmement puissant et utile, mais vous devez comprendre comment les données sous-jacentes sont stockées en mémoire. Si vous avez un tableau de flottants et que vous les affichez comme des ints, (ou vice versa) numpy interprétera les bits sous-jacents du tableau comme des ints.

Par exemple, cela signifie qu'en 1.0tant que flottant 64 bits sur un système little-endian, il sera 4607182418800017408vu comme un int 64 bits, et un tableau de [ 0, 0, 0, 0, 0, 0, 240, 63]si vu comme un uint8. C'est vraiment bien quand vous avez besoin de faire un twiddling de bits sur de grands tableaux, cependant ... Vous avez un contrôle de bas niveau sur la façon dont la mémoire tampon est interprétée.

Joe Kington
la source
Merci pour les très bons conseils! Je lisais le guide de l'utilisateur Numpy et je ne savais pas pourquoi x[np.array([1, 1, 3, 1])] += 1modifié x. Maintenant compris!
tnq177 du
bons conseils! J'ai encore une question. Comment prouver que numpy ne déclenche pas une copie mais juste une vue? id () de python semble incapable de cela.
wuhaochi
3
@wuhaochi Si best une vue de a, alors le b.base is asera True. Une copie (de n'importe quel tableau) aura toujoursarr_copy.base is None
Jürg Merlin Spaak