2016-06-27 3 views
1

У меня проблема с numpy.copy не работает должным образом.Numpy.copy не работает, как предназначен для случайного отбора проб

При использовании его следующим образом, она по-прежнему ссылается на изменение назад в моем первоначальном списке, который я хочу, чтобы избежать:

test = np.copy(random.sample(population_list, 2)) 
test[0][0][0][0] = 1.1111 

Если я распечатать population list после назначения тест, он делает заменить значение в это положение population_list с 1.1111. Моя цель - пробовать из списка, а затем внести некоторые изменения в эти образцы, не затрагивая первоначальный список.

В дальнейшей информации, мой population_list список списков, где первый элемент является NumPy матрица:

print(type(population_list)) 
print(type(population_list[0])) 
print(type(population_list[0][0])) 
print(type(population_list[0][0][0][0])) 

list 
list 
numpy.ndarray 
numpy.float64 

LE: This is how the data looks like. Извините за странный формат, классы на данный момент находятся вне меня.

+0

Таким образом, у вас есть список списков, и по крайней мере один элемент внутреннего списка представляет собой массив с числами numaps. Я задавался вопросом, почему вы повторяете '[]' и не используете что-то вроде '[0,0]'. Знаете ли вы, что производит «random.sample»? Мое предположение - это пара вложенных списков. А что такое копирование 'np.copy'? Список ?, массив? или что-то другое? Почему все гнездование? – hpaulj

+0

На самом деле это 3 уровня вложенности списка. 'random.sample' сохраняет это гнездование. Но 'np.copy' обертывает его в массив, создавая массив 4d, если не существует некоторого промежуточного уровня массива dtype объекта. – hpaulj

+0

Нам нужно увидеть фактический 'population_list' или, по крайней мере, меньшую версию, которая ведет себя одинаково. Прежде чем жаловаться на 'np.copy', нам нужно понять ввод. Вероятно, часть 'random.sample' не имеет значения, поскольку она работает со списками. – hpaulj

ответ

3

Выработать на мои комментарии, я постараюсь, чтобы воссоздать свой список

In [202]: x=np.arange(10.) 

In [223]: x 
Out[223]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) 

In [224]: ll=[[[x]]] # a list 

In [225]: ll[0] # still a list 
Out[225]: [[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]] 

In [226]: ll[0][0] # still a list 
Out[226]: [array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])] 

In [227]: ll[0][0][0] # an array 
Out[227]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) 

In [228]: ll[0][0][0][0] # a float 
Out[228]: 0.0 

In [229]: random.sample(ll,1) # same list nesting 
Out[229]: [[[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]]] 

In [230]: y=np.copy(ll) # a 4d array 

In [231]: y 
Out[231]: array([[[[ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]]]]) 

In [232]: y.shape 
Out[232]: (1, 1, 1, 10) 

Если ll Содержится подсписки разных размеров, мы получим массив объектов

In [233]: ll.append([[2]]) 

In [234]: ll 
Out[234]: [[[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]], [[2]]] 

In [235]: random.sample(ll,2) 
Out[235]: [[[2]], [[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]]] 

In [236]: np.copy(ll) 
Out[236]: 
array([[[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]], 

     [[2]]], dtype=object) # (2,1,1) shape 

играть с это еще немного. Если np.copy является 4d-массивом, то модификация его элемента не изменяет ll или x. Но если есть уровень промежуточного массива объектов, то модификация y изменит ll и x. Это больше похоже на создание мелкой копии списка (ll[:]) в отличие от глубокой копии.

In [270]: ll=[[[x]],[[1,2,3]]] 

In [271]: ll 
Out[271]: [[[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]], [[1, 2, 3]]] 

In [272]: y=np.copy(ll) 

In [273]: y 
Out[273]: 
array([[[array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]], 
     [[1, 2, 3]]], dtype=object) 

In [274]: y[0][0][0][0]=1 

In [275]: y 
Out[275]: 
array([[[array([ 1., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]], 
     [[1, 2, 3]]], dtype=object) 

In [276]: ll 
Out[276]: [[[array([ 1., 1., 2., 3., 4., 5., 6., 7., 8., 9.])]], [[1, 2, 3]]] 

In [277]: x 
Out[277]: array([ 1., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) 

В общем, np.copy не сохраняет структуру вложенных списков списков. Вместо этого он пытается создать массив. Что вы должны использовать, это copy.deepcopy. Это сохраняет структуру списка и копирует значения до конца.

+0

Большое спасибо за этот очень подробный ответ. Это имело смысл намного быстрее, чем я обычно трачу на что-то подобное. Если кто-то натыкается сюда в будущем, также ссылайтесь на http: // stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-the-the-copy-copy, который я нашел весьма полезным для дополнения ответа @ hpaulj –

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