Массив массивов памяти
У меня есть вопрос, касающийся просмотров памяти numpys:
Предположим, у нас есть два массива с памятью:
import numpy as np
import gc
x = np.arange(4*3).reshape(4,3).astype(float)
y = (np.arange(5) - 5).astype(float)
y_ref = y
Мы используем эти (x
, y
) в такой структуре, что мы не можем просто переопределить их, так как пользователь мог связать их для себя (как в y_ref
). Теперь мы хотим объединить их память в одном представлении. Итак, что единый взгляд, скажем, p
разделяет память с обоими массивами.
Я сделал это следующим образом, но не знаю, вызывает ли это утечку памяти:
p = np.empty(x.size+y.size, dtype=float) # create new memory block with right size
c = 0 # current point in memory
# x
p[c:c+x.size].flat = x.flat # set the memory for combined array p
x.data = p[c:c+x.size].data # now set the buffer of x to be the right length buffer of p
c += x.size
# y
p[c:c+y.size].flat = y.flat # set the memory for combined array p
y.data = p[c:c+y.size].data # and set the buffer of x to be the right length buffer of p
Таким образом, теперь мы можем оперировать единым представлением p
или любой из массивов, без необходимости переопределять каждую ссылку на них
x[3] = 10
print p[3*3:4*3]
# [ 10. 10. 10.]
Четное y_ref
получил обновление:
print y[0] # -5
y_ref[0] = 100
print p[x.size] # 100
Это правильный способ установки памяти массива для просмотра в другой массив?
Есть ли очевидный способ объединения памяти массивов, который мне явно не хватает?
Я не уверен, что произойдет со старыми буферами данных x
а также y
поскольку они вне области теперь. Будут ли они освобождены?
Обновление спасибо @Jaime:
p.size
может стать очень большим (в миллиарды) для наборов данных, к которым я обращаюсь (микробиология). Кроме того, эта тема используется в среде с потенциально глубокими структурами, поэтому обновление всех локальных версий может оказаться дорогостоящим. Обновление всех параметров необходимо выполнять в цикле оптимизации, поэтому крайне важно иметь все в памяти.
На самом деле ваш подход был тем, к чему я пришел в первую очередь, так как он был неэффективным, используя обходы Python для обновления всех локальных копий.
1 ответ
Согласно исходному коду, старый буфер данных будет освобожден.
но если на старый буфер ссылается другой массив, это вызовет проблему:
import numpy as np
a = np.zeros(10)
b = np.zeros(10)
c = a[:]
a.data = b
print c