我遇到以下问题:
我想写一个ndarray子类,并为该子类的任何新实例强制执行shape(-1,3),无论是显式构造函数、视图转换还是从模板。
我试了很多东西,但似乎都不管用。我想我还没有完全理解这个过程。非常感谢您的帮助!
import numpy as np
class test(np.ndarray):
def __new__(cls, *args, **kwargs):
return np.ndarray.__new__(cls, *args, **kwargs)
def __array_finalize__(self, obj):
# self.resize(-1,3)
# self.reshape(-1,3)
# self=self.reshape(-1,3)
np.reshape(self,(-1,3))
a=np.array([1,2,3])
b=a.view(test)
c=test(a)
d=a.reshape(-1,3)
print '+++++++'
print a.shape,a
print '+++++++'
print b.shape,b
print '+++++++'
print c.shape,c
print '+++++++'
print d.shape,d
澄清我想做什么:
我有向量场,我想将其一般地处理为3D,因此(:,3)形状和(-1,3)形状的大小调整。我正在寻找一个纯面向对象的解决方案来实现一些额外的方法,以补充NumPy已经提供的方法。
例如,我已经开始纯用ndarrays编写一些东西,但如果我能直接编写,代码的可读性会高得多
normalizedVector = ndarray.view(my3DVectorClass).normalize()
而不是
normalizedVector = ndarray / ( sum(ndarray**2, axis=1)**0.5 )
我的第二个问题:
- 我希望能够不必担心我是否要求形状(3,)或(:,3)数组的规范化版本
- 我希望能够在类方法实现中使用纯线性代数术语,而不必在方法定义中进行索引和错误/维度检查
我想你可能会争辩说只使用my3DVectorClass的实例,但在使用所有SciPy机器时,我必须进行反向视图转换,因为如果我没有错的话,他们会期望ndarray,这会使代码的这些部分有点臃肿。
如果我的逻辑可能有错,我很感激你的建议。我仍然在OOP和SciPy/NumPy的学习曲线上。
已经非常感谢了!
Markus
您应该了解matrix
类是如何实现的。它执行类似的技巧来维护ndims=2
。
然而,我和许多其他人都认为这种伎俩麻烦重重。matrix
类在过去引起了很多问题,因为它只是部分地像普通的ndarray
。请考虑编写函数。上面给出的代码示例将是最可读的,比如:normalizedVector = normalize(ndarray)
。即使使用面向对象的风格,制作更多的子类也不总是最好的设计。
reshape
将尝试使用新形状创建数据视图,如果不能,则将使用新形状来创建数据副本。但原始对象保持不变。要在适当的位置修改形状,可以执行以下操作:
self.shape = (-1, 3)
例如:
>>> a = np.arange(9)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> np.reshape(a, (-1, 3)) # creates a view with the new shape
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> a # but the original object is unchanged
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> a.shape = (-1, 3) # this modifies the original object
>>> a
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
不过,您必须小心,因为如果不进行复制就无法对其进行整形,则会引发AttributeError
:
>>> a = np.arange(36).reshape(6, 6).T
>>> b = np.reshape(a, (-1, 3)) # creates a copy of the data in a
>>> a.shape = (-1, 3) # tries to reshape in-place, and fails
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: incompatible shape for a non-contiguous array