Массив массивов памяти

У меня есть вопрос, касающийся просмотров памяти 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 ответ

Согласно исходному коду, старый буфер данных будет освобожден.

https://github.com/numpy/numpy/blob/6c6ddaf62e0556919a57d510e13ccb2e6cd6e043/numpy/core/src/multiarray/getset.c#L329

но если на старый буфер ссылается другой массив, это вызовет проблему:

import numpy as np

a = np.zeros(10)
b = np.zeros(10)
c = a[:]
a.data = b
print c
Другие вопросы по тегам