Присвоєння масиву масиву з копією


103

Наприклад, якщо у нас є numpyмасив A, і ми хочемо numpyмасив Bз тими ж елементами.

Яка різниця між наступними (див. Нижче) методами? Коли виділяється додаткова пам'ять, а коли ні?

  1. B = A
  2. B[:] = A(те саме, що B[:]=A[:]?)
  3. numpy.copy(B, A)

Відповіді:


127

Усі три версії роблять різні речі:

  1. B = A

    Це пов'язує нове ім'я Bз уже названим об'єктом A. Потім вони посилаються на один і той же об’єкт, тож якщо ви модифікуєте один на місці, ви побачите зміни і через інший.

  2. B[:] = A(те саме, що B[:]=A[:]?)

    Це копіює значення з Aіснуючого масиву B. Два масиви повинні мати однакову форму для цього. B[:] = A[:]робить те ж саме (але B = A[:]зробив би щось більше, як 1).

  3. numpy.copy(B, A)

    Це не юридичний синтаксис. Ви , ймовірно , мав в виду B = numpy.copy(A). Це майже те саме, що і 2, але він створює новий масив, а не повторно використовує Bмасив. Якщо б не було інших посилань на попереднє Bзначення, кінцевий результат буде таким самим, як 2, але він буде використовувати більше пам'яті тимчасово під час копіювання.

    А може, ви мали на увазі numpy.copyto(B, A), що є законним і еквівалентно 2?


21
@Mr_and_Mrs_D: Numpy масиви працюють інакше, ніж списки. Нарізання масиву не робить копію, воно просто створює новий перегляд даних існуючого масиву.
Blckknght

Що означає but B = A[:] would do something more like 1? Відповідно до цього stackoverflow.com/a/2612815 new_list = old_list[:] також є копією.
мрглум

4
@mrgloom: Numpy масиви працюють по-іншому, ніж списки, коли мова йде про нарізання та копіювання їх вмісту. Масив - це "перегляд" базового блоку пам'яті, де зберігаються числові значення. Виконання фрагмента, як-от подібний some_array[:], створить новий об’єкт масиву, але цей новий об'єкт буде виглядом тієї самої пам'яті, що і вихідний масив, який не буде скопійовано. Тому я сказав, що це більше схоже B = A. Це займає лише O(1)простір та час, а не O(n)кожну справжню копію.
Blckknght

27
  1. B=A створює довідку
  2. B[:]=A робить копію
  3. numpy.copy(B,A) робить копію

останні два потребують додаткової пам'яті.

Щоб зробити глибоку копію, вам потрібно скористатися B = copy.deepcopy(A)


2
Посилаючись на ваш другий приклад: B[:] = Aце НЕ робить глибоку копію масивів об'єктів типу, наприклад A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O'). Тепер спробуйте B[:] = A; B[0][0]=99, це змінить перший елемент і в А, і в В ! Наскільки мені відомо, немає іншого способу гарантувати глибоку копію, навіть нумерованого масиву, ніжcopy.deepcopy
Рольф Бартстра

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.