Как мне заставить append работать с массивами так, как задумано?

#python #numpy

#python #numpy

Вопрос:

У меня проблема с этим кодом. Мне кажется, я делаю что-то неправильно.

  import numpy as np

 array = np.zeros(10)

 arrays = []

 for i in range(len(array)):
    array[i] = 1
    arrays.append(array)

 print(arrays[0])
  

Я ожидал получить:[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
Но я получаю:[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]

Это последний массив, который я добавил к массивам, а не первый. Почему это происходит и, что более важно, что я могу сделать, чтобы получить желаемый результат?

Комментарии:

1. Подсказка: сколько разных массивов в вашем коде? Сколько массивов вы создаете?

2. Также почему бы не использовать np.eye ?

3. преобразовать массив в массив nympy

4. Я использовал простой пример, чтобы показать, что происходит, на самом деле я использую массив матриц со значениями, которые я получаю из данных, но проблема та же.

5. Когда вы изменяете список объектов, словарь ndarray и добавляете его в список, вам нужно добавить копию, а не объект, который вы продолжаете изменять. В противном случае все элементы списка в конечном итоге будут выглядеть одинаково — потому что это один и тот же объект. Добавление списка не сохраняет копию автоматически; вы должны сделать это самостоятельно.

Ответ №1:

Я думаю, вы ожидаете:

 arrays.append(array)
  

чтобы добавить КОПИЮ вашего основного массива в список массивов. Но это не то, что вы делаете. Вы каждый раз отправляете другую ссылку на один и тот же массив:

 arrays.append(array)
  

итак, в конце вашего цикла у вас есть список массивов с 10 ссылками на тот же исходный массив, который вы создали. К тому времени вы присвоите каждому значению этого МАССИВА значение 1. Итак, вы получаете, что первое значение в массивах содержит массив с каждым значением, равным 1, потому что каждый массив в массивах является одним и тем же массивом.

Если вы на самом деле копируете новый массив каждый раз в массивы, бьюсь об заклад, вы получите то, что ожидали. Для этого измените эту строку на:

 arrays.append(array.copy())
  

Вот полная версия вашей программы с этим исправлением. Я также изменил его, чтобы печатать все 10 массивов в arrays:

 def main():
    import numpy as np

    array = np.zeros(10)

    arrays = []

    for i in range(len(array)):
        array[i] = 1
        arrays.append(array.copy())

    for array in arrays:
        print(array)
  

Результат:

 [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[1. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[1. 1. 1. 0. 0. 0. 0. 0. 0. 0.]
[1. 1. 1. 1. 0. 0. 0. 0. 0. 0.]
[1. 1. 1. 1. 1. 0. 0. 0. 0. 0.]
[1. 1. 1. 1. 1. 1. 0. 0. 0. 0.]
[1. 1. 1. 1. 1. 1. 1. 0. 0. 0.]
[1. 1. 1. 1. 1. 1. 1. 1. 0. 0.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 0.]
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
  

Комментарии:

1. array это не список; это массив NumPy. Они выглядят похожими, но типы очень разные и их не следует путать.

2. Ого! Спасибо, что указали на это. Затем я показал, как исправить это неправильно, lol! Я не знаю numpy. Я показал проблему и идею о том, как ее исправить. Если парню действительно нужен массив numpy, я надеюсь, что он сможет исправить это сам. Тем не менее … вы правы… Я исправлю свой ответ. — думаю, мой вывод, выглядящий по-другому при печати, должен был меня насторожить. Иногда я веду себя не так уж блестяще. Еще раз спасибо!

Ответ №2:

просто добавьте это изменение:

 arrays.append(np.array(array))
  

Комментарии:

1. Вы допустили ту же ошибку, что и я изначально в своем ответе. массив не является list…it это массив numpy. Итак, здесь вы меняете тип контейнера, а не просто копируете его. Как я уже сказал, изначально я допустил ту же ошибку. Потребовалось @user2357112, чтобы указать на ошибку моих способов.

Ответ №3:

Фактический способ сделать это в numpy — с np.tri() :

 np.tri(10)
Out[]:
array([[ 1.,  0.,  0., ...,  0.,  0.,  0.],
       [ 1.,  1.,  0., ...,  0.,  0.,  0.],
       [ 1.,  1.,  1., ...,  0.,  0.,  0.],
       ..., 
       [ 1.,  1.,  1., ...,  1.,  0.,  0.],
       [ 1.,  1.,  1., ...,  1.,  1.,  0.],
       [ 1.,  1.,  1., ...,  1.,  1.,  1.]])
  

Ответ №4:

Возможно, вы ищете это, просто добавили условие if в свой код

 import numpy as np

array = np.zeros(10)

arrays = []

for i in range(len(array)):
    if i==0:
        array[i] = 1
    arrays.append(array)

print(arrays[0])
out: [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
  

Ответ №5:

Вы можете использовать array.copy() метод, определенный для массивов numpy, как предложил @ Steve.

Поскольку это уже использовалось в одном из ответов (@Steve’s answer) на эту проблему, поэтому я выбираю другой подход, т.е. deepcopy() function для получения результата.

 import numpy as np 
from copy import deepcopy

array = np.zeros(10)
arrays = []

for i in range(len(array)):
    array[i] = 1
    arrays.append(deepcopy(array))

print(arrays)
# [array([1., 0., 0., 0., 0., 0., 0., 0., 0., 0.]), array([1., 1., 0., 0., 0., 0., 0., 0., 0., 0.]), array([1., 1., 1., 0., 0., 0., 0., 0., 0., 0.]), array([1., 1., 1., 1., 0., 0., 0., 0., 0., 0.]), array([1., 1., 1., 1., 1., 0., 0., 0., 0., 0.]), array([1., 1., 1., 1., 1., 1., 0., 0., 0., 0.]), array([1., 1., 1., 1., 1., 1., 1., 0., 0., 0.]), array([1., 1., 1., 1., 1., 1., 1., 1., 0., 0.]), array([1., 1., 1., 1., 1., 1., 1., 1., 1., 0.]), array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])]

print(arrays[0])
# [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

print(arrays[-1])
# [1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
  

Комментарии:

1. Спасибо за ваш комментарий @tripleee . Я обновил свой ответ. Я знаю, что array.copy() это хороший выбор, но это уже часть 1 ответа, поэтому используется deepcopy() для получения результата.