オブジェクト属性を介して「グローバル」numpy配列のスライスを参照しようとしています。ここで私はクラスの構造は、それがユースケースのようになると思います。今、私が取得するグローバルnumpy配列のサブセクションまたはスライスをpythonオブジェクトを介して設定する
>>> n.x = numpy.array([11, 12, 13])
、によってn.x
属性を通じてn.P
に値を代入したい、正常に動作します
>>> n = Node()
>>> print n.P
[ 1 2 3 4 5 6 7 8 9 10]
>>> print n.x
[1 2 3]
>>> print n.x[1:3]
[2 3]
:ここ
import numpy
class X:
def __init__(self, parent):
self.parent = parent
self.pid = [0, 1, 2]
def __getattr__(self, name):
if name == 'values':
return self.parent.P[self.pid]
else:
raise AttributeError
class Node:
def __init__(self):
self.P = numpy.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
self._values = X(self)
def __getattr__(self, name):
if name == 'x':
return self._values.values
else:
raise AttributeError
は、ユースケースです
>>> print n.P
[ 11 12 13 4 5 6 7 8 9 10]
または取得する
>>> n.x[1:3] = numpy.array([77, 88])
、によってスライスに値を代入し、
>>> print n.P
[ 11 77 88 4 5 6 7 8 9 10]
しかし、私の人生のために、私はこの割り当ての作業を取得するために苦労しています。私はそれが__setattr__
と__setitem__
を使用して簡単だと思ったが、一日後でも私はまだそれを管理していない。
最終的には、クラスの形が再構成される多次元配列としてn.x
が返されますが、ベクトルであるn.P
に格納されます。問題を単純化するためにこれを削除しました。
私はこれについていくつかの助けが好きです。誰もこれを前にしたことがありますか?またはこれを行う方法を提案しますか?
ご協力いただきありがとうございます。
SOLUTION
だから私の周りにつまずきの多くの日は、解決策を見つけた後。私は、これを簡素化して洗練させることができると思う。解決策は、NodeオブジェクトにXオブジェクトを作成することです。それが取得されると、親ノードとpidを知っている一時numpyオブジェクト(Values)を返します。 setslice _関数は、グローバルP配列を新しい値で更新する際に定義されています。 Xオブジェクトが割り当てられている場合、Valuesオブジェクトは返されませんが、グローバルP値は直接設定されます。
無効である可能性がある2つのポイント:1.ノードおよびXオブジェクトはオブジェクトのサブクラスでなければなりません。 2.高次元配列を設定する場合は、代わりに__setitem__
を使用する必要があります。これは1D配列またはリストでは機能しません。
私が言ったように、私は完全に理解しているかどうかわからないので、このコードは改善できると思っています。私は改善と提案をしてうれしいです。
おかげさまで、特にBagoに感謝します。
ここに私の最終的なコードです。
import numpy
class Values(numpy.ndarray):
def __new__(cls, input_array, node, pids):
obj = numpy.asarray(input_array).view(cls)
obj.node = node
obj.pids = pids
return obj
def __setslice__(self, i, j, values):
self.node._set_values(self.pids[i:j], values)
class X(object):
def __get__(self, instance, owner):
p = instance.P[instance.pids]
return Values(p, instance, instance.pids)
def __set__(self, instance, values):
instance.P[instance.pids] = values
class Node(object):
x = X()
def __init__(self, pids=[0, 1, 2]):
self.P = numpy.arange(11)
self.pids = pids
def _set_values(self, pids, values):
self.P[pids] = values
node = Node(pids=[4, 5, 6, 7])
print '\nInitial State:'
print 'P =', node.P
print 'x =', node.x
print 'x[1:3] =', node.x[1:3]
print '\nSetting node.x = [44, 55, 66, 77]:'
node.x = [44, 55, 66, 77]
print 'P =', node.P
print 'x =', node.x
print 'x[1:3] =', node.x[1:3]
print '\nSetting node.x[1:3] = [100, 200]:'
node.x[1:3] = [100, 200]
print 'P =', node.P
print 'x =', node.x
print 'x[1:3] =', node.x[1:3]
ありがとうございます。それは主に動作しますが、nx [1:3] = numpy.array([77、88])は実行できず、nP = numpy.array([1、77、88、4、5、6、7、8、9 、10])。私はどこでも@ values.setitemデコレータを見てきましたが、運はありません。 – duane
バゴありがとうございます。私もそう思っていました。私はコピーの代わりにスライスのポインタを渡す方法を探し始めました。私の最初の実装は、後でPに手動で関数を実行することで追加したXに値を格納することでしたが、私はそれをやめたいと思っています。その間に関数を使用してスライスを更新しなければならない場合があります。つまり、n.set_values(スライス、値)です。私はsetitemとsetattrを検出し、関数呼び出しとしてXの値を検出する追加のダミーオブジェクトについて考えています。それがうまくいくかどうかわからない、私はそれの周りに私の頭をかなり得ることはできません。とにかくありがとう。 – duane