【发布时间】:2016-10-16 20:15:03
【问题描述】:
我在numpy's documentation 之后创建了一个从 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)
我得到了预期的结果;也就是dot函数保持对象的子类化:
<class '__main__.Atom3D'> 1: ( 5.000, 5.000, 5.000)
<class '__main__.Atom3D'> 1: ( 5.000, 5.000, 5.000)
但是,当我尝试将相同的 np.dot 应用于这些对象的数组时,子类会丢失。因此,执行:
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.-
【问题讨论】: