Affectation de tableau Numpy avec copie

103

Par exemple, si nous avons un numpytableau Aet que nous voulons un numpytableau Bavec les mêmes éléments.

Quelle est la différence entre les méthodes suivantes (voir ci-dessous)? Quand de la mémoire supplémentaire est-elle allouée et quand ne l'est-elle pas?

  1. B = A
  2. B[:] = A(même que B[:]=A[:]?)
  3. numpy.copy(B, A)
mrgloom
la source

Réponses:

127

Les trois versions font des choses différentes:

  1. B = A

    Cela lie un nouveau nom Bà l'objet existant déjà nommé A. Ensuite, ils font référence au même objet, donc si vous en modifiez un sur place, vous verrez également le changement à travers l'autre.

  2. B[:] = A(même que B[:]=A[:]?)

    Cela copie les valeurs Adans un tableau existant B. Les deux tableaux doivent avoir la même forme pour que cela fonctionne. B[:] = A[:]fait la même chose (mais B = A[:]ferait quelque chose de plus comme 1).

  3. numpy.copy(B, A)

    Ce n'est pas une syntaxe légale. Vous vouliez probablement dire B = numpy.copy(A). C'est presque la même chose que 2, mais cela crée un nouveau tableau, plutôt que de réutiliser le Btableau. S'il n'y avait pas d'autres références à la Bvaleur précédente , le résultat final serait le même que 2, mais il utilisera plus de mémoire temporairement pendant la copie.

    Ou peut-être voulez-vous dire numpy.copyto(B, A), ce qui est légal et équivaut à 2?

Blckknght
la source
21
@Mr_and_Mrs_D: Les tableaux Numpy fonctionnent différemment des listes. Le découpage d'un tableau ne fait pas de copie, il crée simplement une nouvelle vue sur les données du tableau existant.
Blckknght
Que veut-on dire but B = A[:] would do something more like 1? Selon ce stackoverflow.com/a/2612815 new_list = old_list[:] est également une copie.
mrgloom
4
@mrgloom: les tableaux Numpy fonctionnent différemment des listes lorsqu'il s'agit de découper et de copier leur contenu. Un tableau est une «vue» d'un bloc de mémoire sous-jacent où les valeurs numériques sont stockées. Faire une tranche comme some_array[:]cela créera un nouvel objet tableau, mais ce nouvel objet sera une vue de la même mémoire que le tableau d'origine, qui n'aura pas été copié. C'est pourquoi j'ai dit que c'était plus comme ça B = A. Cela ne prend que de l' O(1)espace et du temps, plutôt que le O(n)besoin d'une copie réelle.
Blckknght
27
  1. B=A crée une référence
  2. B[:]=A fait une copie
  3. numpy.copy(B,A) fait une copie

les deux derniers ont besoin de mémoire supplémentaire.

Pour créer une copie complète, vous devez utiliser B = copy.deepcopy(A)

Mailerdaimon
la source
2
En vous référant à votre deuxième exemple: B[:] = Ane fait pas de copie complète des tableaux de type objet, par exemple A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O'). Maintenant, essayez B[:] = A; B[0][0]=99, cela changera le premier élément à la fois dans A et B ! À ma connaissance, il n'y a pas d'autre moyen de garantir une copie profonde, même d'un tableau numpy, quecopy.deepcopy
Rolf Bartstra
11

C'est la seule réponse qui fonctionne pour moi:

B=numpy.array(A)
Woeitg
la source