Python: добавление numpy.array к списку python перезаписывает предыдущие элементы - PullRequest
0 голосов
/ 06 марта 2019

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

Затем я увеличиваю время с заданным временным шагом и вычисляю орбиту. Проблема возникает, когда я пытаюсь сохранить рассчитанные позиции в пустом списке. Вот мой код:

## Initial position, velocity, and acceleration
r = np.array([20., 20., 0.])
v = np.array([0., 1., 0.])
g = acc(*r) #calculates acceleration from a function

## empty list to store position data
posdata = []

## Orbit integration
dt = 0.1
for t in np.arange(0, 1000, dt):
    v += 0.5 * g * dt
    r += v * dt
    if t%100 == 0:
        print(r) #check if r actually changes
    g = acc(*r)
    v += 0.5 * g * dt
    posdata.append(r)

Вот что я ожидаю получить:

posdata
>>> [array([19.999875, 20.099875,  0.]), array([19.99950125, 20.19950001,  0.]), array([19.99887999, 20.29887502,  0.]), ...]

Но я на самом деле понимаю:

>>> [array([-17.57080611, -34.03696644,   0.]), array([-17.57080611, -34.03696644,   0.]), array([-17.57080611, -34.03696644,   0.])]

Все элементы идентичны последнему рассчитанному элементу. Как видите, я проверил, действительно ли r меняется, и это так. Я думаю, что это связано с тем, что r является массивом, но я не знаю, как это исправить.

Ответы [ 2 ]

1 голос
/ 06 марта 2019

Когда вы добавляете массив r к списку, добавляется только ссылка на объект массива. А поскольку объекты numpy.array являются изменяемыми, все ссылки обновляются на месте. Для этого вы можете либо

  • добавить массив как список к posdata как список

posdata.append (r.tolist ())

Или

  • добавить массив как новый объект numpy.array к posdata

    posdata.append (np.array (г))

1 голос
/ 06 марта 2019

Вы добавляете один и тот же объект каждый раз, когда создаете список из множества ссылок на один и тот же объект.

[r, r, r, r, r, r, r]

Поскольку объект является изменяемым, при обновлении объектаизменение влияет на весь список ссылок.

Вам необходимо создать копию объекта, когда вы добавляете его в свой список.

Попробуйте вместо этого

posdata.append(r.copy())

Теперь у вас будет другой объект в каждом месте списка.

[r1, r2, r3, r4, r5, r6, r7]

...