2016-06-02 3 views
1

У меня есть массив numpy различных массивов numpy, и я хочу сделать глубокую копию массивов. Я узнал следующее:Глубокая копия np.array из np.array

import numpy as np 

pairs = [(2, 3), (3, 4), (4, 5)] 
array_of_arrays = np.array([np.arange(a*b).reshape(a,b) for (a, b) in pairs]) 

a = array_of_arrays[:] # Does not work 
b = array_of_arrays[:][:] # Does not work 
c = np.array(array_of_arrays, copy=True) # Does not work 
d = np.array([np.array(x, copy=True) for x in array_of_arrays]) 

array_of_arrays[0][0,0] = 100 
print a[0][0,0], b[0][0,0], c[0][0,0], d[0][0,0] 

Является ли лучшим способом для этого? Есть ли функция глубокой копии, которую я пропустил? И как лучше всего взаимодействовать с каждым элементом в этом массиве массивов разного размера?

+0

Вы действительно должны расширять линии «не работает». – hpaulj

ответ

4
import numpy as np 
import copy 

pairs = [(2, 3), (3, 4), (4, 5)] 
array_of_arrays = np.array([np.arange(a*b).reshape(a,b) for (a, b) in pairs]) 

a = copy.deepcopy(array_of_arrays) 

Не стесняйтесь узнать больше об этом here.

О, вот простейший тест:

a[0][0,0] 
print a[0][0,0], array_of_arrays[0][0,0] 
2

Избитый на одну минуту. В самом деле, здесь встречается глубокая копия.

К вашему второму вопросу относится индексирование: у меня есть ощущение, что вам может быть лучше с простым списком или структурой данных словарного типа здесь. np.arrays имеют смысл прежде всего, если каждый элемент массива имеет тот же тип. Конечно, вы можете утверждать, что каждый элемент в массиве array_of_arrays является другим массивом, но в чем преимущество того, что они собраны в массив numpy вместо простого списка?

list_of_arrays = [np.arange(a*b).reshape(a,b) for (a, b) in pairs] 
2
In [276]: array_of_arrays 
Out[276]: 
array([array([[0, 1, 2], 
     [3, 4, 5]]), 
     array([[ 0, 1, 2, 3], 
     [ 4, 5, 6, 7], 
     [ 8, 9, 10, 11]]), 
     array([[ 0, 1, 2, 3, 4], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19]])], dtype=object) 

array_of_arrays является dtype=object; это означает, что каждый элемент массива является указателем на объект, где в памяти. В этом случае эти элементы представляют собой массивы разных размеров.

a = array_of_arrays[:] 

a является новый массив, но вид array_of_arrays; то есть он имеет тот же буфер данных (который в этом случае является списком указателей).

b = array_of_arrays[:][:] 

Это просто взгляд. Второй результат [:] действует на результат первого.

c = np.array(array_of_arrays, copy=True) 

Это то же самое, что и array_of_arrays.copy(). c имеет новый буфер данных, копии оригиналов

Если я заменить элемент c, это не повлияет на array_of_arrays:

c[0] = np.arange(3) 

Но если изменить элемент c, он будет изменять тот же элемент в array_of_arrays - потому что они оба указывают на один и тот же массив.

То же самое относится к вложенным спискам списков. То, что array добавляет, является корпусом view.

d = np.array([np.array(x, copy=True) for x in array_of_arrays]) 

В этом случае вы делаете копии отдельных элементов. Как отмечали другие, существует функция deepcopy. Он был разработан для таких вещей, как списки списков, но также работает и с массивами. Это в основном делает то, что вы делаете с d; рекурсивная работа над деревом вложенности.

В общем случае массив объектов подобен вложенности списков.Несколько операций пересекают границу объекта, например.

array_of_arrays+1 

, но даже это эффективно является

np.array([x+1 for x in array_of_arrays]) 

Одна вещь, что массив объектов добавляет, по сравнению со списком, это такие операции, как reshape. array_of_arrays.reshape(3,1) делает его 2d; если у него было 4 элемента, вы могли бы сделать array_of_arrays.reshape(2,2). Иногда это удобно; в других случаях это боль (сложнее повторять).

Смежные вопросы