Назначение массива Numpy с копией

105

Например, если у нас есть numpyмассив A, и нам нужен numpyмассив Bс такими же элементами.

В чем разница между следующими (см. Ниже) методами? Когда выделяется дополнительная память, а когда нет?

  1. B = A
  2. B[:] = A(так же, как B[:]=A[:]?)
  3. numpy.copy(B, A)
Мрглум
источник

Ответы:

129

Все три версии делают разные вещи:

  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?

Blckknght
источник
21
@Mr_and_Mrs_D: массивы Numpy работают иначе, чем списки. При нарезке массива не создается копия, а просто создается новое представление для существующих данных массива.
Blckknght
Что имеется в виду but B = A[:] would do something more like 1? Согласно этому stackoverflow.com/a/2612815 new_list = old_list[:] также является копией.
mrgloom
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)

Mailerdaimon
источник
2
Ссылаясь на ваш второй пример: B[:] = Aэто не делает глубокую копию массивов объектов типа, например A = np.array([[1,2,3],[4,5]]); B = np.array([None,None], dtype='O'). Теперь попробуйте B[:] = A; B[0][0]=99, это изменит первый элемент как в A, так и в B ! Насколько мне известно, нет другого способа гарантировать глубокую копию, даже numpy-array, чемcopy.deepcopy
Рольф Бартстра
11

Для меня это единственный рабочий ответ:

B=numpy.array(A)
Woeitg
источник