numpy配列をサブクラス化すると、次の問題が発生します
例えば:
import numpy
class Example(numpy.ndarray):
def __new__(cls, x, y):
dt = [('x', 'float'), ('y', 'float')]
buffer = numpy.array(zip(x, y),dtype=dt)
obj = super(Example, cls).__new__(cls, buffer.shape, dtype=dt,
buffer=buffer)
obj.x = numpy.array(x, dtype='float')
obj.y = numpy.array(y, dtype='float')
return obj
def __array_finalize__(self, obj):
if obj is None: return
self.x = getattr(obj, 'x', None)
self.y = getattr(obj, 'y', None)
obj.xとobj ['x']を使用して操作を行った場合、一方が他方を変更することはありません。たとえば、これらの操作は異なる結果を示します
x = [1,2,3,4]
y = [1,1,1,1]
obj = Example(x,y)
obj.x = obj.x / 2.
print obj.x, obj['x']
または
obj = Example(x,y)
obj['x'] = obj['x'] / 2.
print obj.x, obj['x']
それらの1つ(obj.xまたはobj ['x'])で操作を行うたびに、もう1つも変更されるようにするにはどうすればよいですか?
使用する[('x', 'float'), ('y', 'float')]
データ型は、作成するためにnumpyの指示するように構成、配列の名前フィールドを持つx
としますy
。あなたが示したように、それらは括弧を使用してアクセスされます。これでobj.<name>
、クラスに属性(を使用してアクセス)も追加しました。ただし、属性の新しい配列を作成しました。属性表記を修正するには、あなたが持っている必要がありますx
し、y
むしろ別の配列よりも、それらの名前によって配列フィールドにポイントを属性を。だから変更
obj.x = numpy.array(x, dtype='float')
obj.y = numpy.array(y, dtype='float')
に
obj.x = obj['x']
obj.y = obj['y']
これを編集すると、質問の2番目のテストケースのみが修正されます。割り当てるx
か、y
まだ属性として新しいオブジェクトを割り当てではなく、更新しますx
かy
。これを修正するに__setattr__
は、クラスのメソッドを変更する必要があります(ここを参照)
def __setattr__(self, attr, value):
if attr in ['x', 'y']:
getattr(self, attr)[:] = attr
else:
setattr(self, attr, value)
ただし、Numpyには、属性としてフィールドにアクセスできるようにする配列型がすでにあります。このように使えます
obj = np.array(np.r_[x, y], dtype=[('x', 'float'), ('y', 'float')])
obj = obj.view(np.recarray)
おめでとうございます!レコード配列を効果的に再実装しました(np.recarray
属性または関数ndarray
が持つ名前に一致するフィールドへのアクセスは許可されません。したがって、コードで許可されているのに、のような名前mean
またはndim
外れている名前があります)。すでに持っている何かを作成するのに何時間も費やすとき、それは常に良い(そして非常にイライラする)兆候です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加