Numpy przypisywanie tablicy z kopiowaniem

103

Na przykład, jeśli mamy numpytablicę Ai chcemy numpytablicy Bz takimi samymi elementami.

Jaka jest różnica między następującymi (patrz poniżej) metodami? Kiedy przydzielana jest dodatkowa pamięć, a kiedy nie?

  1. B = A
  2. B[:] = A(tak samo jak B[:]=A[:]?)
  3. numpy.copy(B, A)
mrgloom
źródło

Odpowiedzi:

127

Wszystkie trzy wersje robią różne rzeczy:

  1. B = A

    Powoduje to powiązanie nowej nazwy Bz istniejącym już nazwanym obiektem A. Następnie odnoszą się do tego samego obiektu, więc jeśli zmodyfikujesz jeden na miejscu, zobaczysz zmianę również w drugim.

  2. B[:] = A(tak samo jak B[:]=A[:]?)

    Spowoduje to skopiowanie wartości z Ado istniejącej tablicy B. Aby to zadziałało, obie tablice muszą mieć ten sam kształt. B[:] = A[:]robi to samo (ale B = A[:]zrobiłby coś bardziej jak 1).

  3. numpy.copy(B, A)

    To nie jest legalna składnia. Prawdopodobnie miałeś na myśli B = numpy.copy(A). Jest to prawie to samo, co 2, ale tworzy nową tablicę zamiast ponownie jej używać B. Gdyby nie było innych odniesień do poprzedniej Bwartości, wynik końcowy byłby taki sam jak 2, ale tymczasowo podczas kopiowania zużywałby więcej pamięci.

    A może chodziło Ci o to numpy.copyto(B, A), co jest legalne i odpowiada 2?

Blckknght
źródło
21
@Mr_and_Mrs_D: Numpy tablice działają inaczej niż listy. Cięcie tablicy na plasterki nie powoduje jej skopiowania, a jedynie tworzy nowy widok danych istniejącej tablicy.
Blckknght
Co to znaczy but B = A[:] would do something more like 1? Według tego stackoverflow.com/a/2612815 new_list = old_list[:] również jest kopią.
mrgloom
4
@mrgloom: Tablice Numpy działają inaczej niż listy, jeśli chodzi o cięcie i kopiowanie ich zawartości. Tablica to „widok” podstawowego bloku pamięci, w którym przechowywane są wartości liczbowe. Wykonanie takiego wycinka jak some_array[:]utworzy nowy obiekt tablicy, ale ten nowy obiekt będzie widokiem tej samej pamięci, co oryginalna tablica, która nie zostanie skopiowana. Dlatego powiedziałem, że bardziej przypomina B = A. Zajmuje tylko O(1)przestrzeń i czas, a nie wszystko, O(n)czego potrzebowałaby prawdziwa kopia.
Blckknght
27
  1. B=A tworzy odniesienie
  2. B[:]=A tworzy kopię
  3. numpy.copy(B,A) tworzy kopię

ostatnie dwa wymagają dodatkowej pamięci.

Aby zrobić głęboką kopię, musisz użyć B = copy.deepcopy(A)

Mailerdaimon
źródło
2
Odnosząc się do drugiego przykładu: B[:] = Aczy nie zrobić głęboki kopii tablic obiektów typu, np A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O'). Teraz spróbuj B[:] = A; B[0][0]=99, to zmieni pierwszy element zarówno w A, jak i B ! O ile mi wiadomo, nie ma innego sposobu na zagwarantowanie głębokiej kopii, nawet tablicy numpy, niżcopy.deepcopy
Rolf Bartstra
11

To jedyna działająca odpowiedź dla mnie:

B=numpy.array(A)
Biada
źródło