をufunc適用した後、容器内numpyのサブクラスを維持し、(それをより読みやすくするために、属性の数を減らす)ように見えます: 私は<a href="http://docs.scipy.org/doc/numpy-1.10.1/user/basics.subclassing.html" rel="nofollow">numpy's documentation</a>を以下のnumpyののndarrayから派生したクラスを作成した
import numpy as np
class Atom3D(np.ndarray):
__array_priority__ = 11.0
def __new__(cls, idnum, coordinates):
# Cast numpy to be our class type
assert len(coordinates) == 3
obj = np.asarray(coordinates, dtype= np.float64).view(cls)
# add the new attribute to the created instance
obj._number = int(idnum)
# Finally, we must return the newly created object:
return obj
def __array_finalize__(self, obj):
self._number = getattr(obj, '_number', None)
def __array_wrap__(self, out_arr, context=None):
return np.ndarray.__array_wrap__(self, out_arr, context)
def __repr__(self):
return "{0._number}: ({0[0]:8.3f}, {0[1]:8.3f}, {0[2]:9.3f})".format(self)
とき私はオブジェクトにnumpyのufuncを適用するテストを実行します:
a1 = Atom3D(1, [5., 5., 5.])
print type(a1), repr(a1)
m = np.identity(3)
a2 = np.dot(a1, m)
print type(a2), repr(a2)
私は期待される結果を得ます。つまり、ドット関数はオブジェクトのサブクラス続けて:私は、これらのオブジェクトの配列に同じnp.dotを適用しようとすると、
<class '__main__.Atom3D'> 1: ( 5.000, 5.000, 5.000)
<class '__main__.Atom3D'> 1: ( 5.000, 5.000, 5.000)
をしかし、サブクラスは失われます。このように、実行:
print "regular"
atom_list1 = [a1, a2, a3]
atom_list2 = np.dot(atom_list1, m)
for _ in atom_list2:
print type(_), repr(_)
print "numpy array"
atom_list1 = np.array([a1, a2, a3], dtype=np.object)
atom_list2 = np.dot(atom_list1, m)
for _ in atom_list2:
print type(_), repr(_)
することは私にこの与える:
regular
<type 'numpy.ndarray'> array([ 5., 5., 5.])
<type 'numpy.ndarray'> array([ 6., 4., 2.])
<type 'numpy.ndarray'> array([ 8., 6., 8.])
numpy array
<type 'numpy.ndarray'> array([5.0, 5.0, 5.0], dtype=object)
<type 'numpy.ndarray'> array([6.0, 4.0, 2.0], dtype=object)
<type 'numpy.ndarray'> array([8.0, 6.0, 8.0], dtype=object)
など__sub__
などの他の操作のために行くだろうと同じ:
print "regular"
a1 = Atom3D(1, [5., 5., 5.])
a2 = a1 - np.array([3., 2., 0.])
print type(a2), repr(a2)
print "numpy array"
a1 = Atom3D(1, [5., 5., 5.])
a2 = Atom3D(2, [6., 4., 2.])
a3 = Atom3D(3, [8., 6., 8.])
atom_list1 = np.array([a1, a2, a3], dtype=np.object)
atom_list2 = atom_list1 - np.array([3., 2., 0.])
for _ in atom_list2:
print type(_), repr(_)
が得られます:
regular
<class '__main__.Atom3D'> 1: ( 2.000, 3.000, 5.000)
numpy array
<type 'numpy.ndarray'> array([2.0, 3.0, 5.0], dtype=object)
<type 'numpy.ndarray'> array([3.0, 2.0, 2.0], dtype=object)
<type 'numpy.ndarray'> array([5.0, 4.0, 8.0], dtype=object)
私は見てきましたがどうやって私が間違っているのか分からない。
ありがとうございます!
J.-
私は混乱を避けるために私の例でこれを変更しました。しかし、これは私の質問に答えるものではありません。これは、numpyのufuncを適用すると、list/np.array内のオブジェクトのサブクラス化が失われることです。十分にはっきりしていないかもしれませんか?ちょっとでも私の質問を少し言い直しました。この 'Atom3D'オブジェクトの全部に翻訳(' __sub__'と '__add__')と回転(' np.dot')を適用できるようにするために、 'np.array'が必要です私が毎回それらのすべてをループすることを避けたいのであれば... – jaumebonet
私はあなたのクラスでいくつかのことを試しました。 – hpaulj
ああ! OK!今私はそれを得る!私はこれが私のために働くと思う! 2つのアトムを追加しても機能しないようですが、それでも問題はありません。配列や行列のみを適用してください。ありがとう!! – jaumebonet