4

numpys メモリ ビューに関する質問があります。

メモリを備えた 2 つの配列があるとします。

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)、それらを再定義することはできません。ここで、彼らの記憶を 1 つのビューにまとめたいと思います。したがって、単一のビューは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階層トラバーサルを使用してすべてのローカルコピーを更新するのは非効率的だったからです。

4

1 に答える 1

3

ソース コードによると、古いデータ バッファーは解放されます。

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
于 2014-05-14T11:22:08.657 に答える