如何在保留继承的同时使用 numpy 制作二维数组
How to make 2D arrays with numpy while preserving inheritance
我有一个多边形 class,它使用 2d ndarray 来存储它的点。 class中的每个点都是一个Vectorclass的实例,这个Vectorclass继承了numpy的ndarray。我目前正在使用 numpy.vstack 附加点,但问题是我的向量实例被转换为它们的父实例 class、numpy.ndarray.
import numpy as np
class Vector(np.ndarray):
def __new__(cls, *args, **kwargs):
arr = np.asarray([args[0], args[1], args[2]]).view(cls)
arr = arr.astype('float64')
return arr
class Polygon(object):
def __init__(self):
self.points = np.array([]).reshape(0, 3)
def append_point(self, point):
self.points = np.vstack([self.points, point])
poly = Polygon()
vec1 = Vector(1, 2, 3)
print(type(vec1)) # output: <class '__main__.Vector'>
poly.append_point(vec1)
print(poly.points) # output: [[1. 2. 3.]]
print(type(poly.points[0])) # output: <class 'numpy.ndarray'>
有更好的方法吗?
如果你想保留子类,我认为你需要覆盖 __array_function__
方法:
class Vector(np.ndarray):
def __new__(cls, *args, **kwargs):
arr = np.asarray([args[0], args[1], args[2]]).view(cls)
arr = arr.astype('float64')
return arr
def __array_function__(self, func, types, args, kwargs):
x,y = args[0]
return func([x.view(np.ndarray), y.view(np.ndarray)], **kwargs).view(Vector)
这会给
poly = Polygon()
vec1 = Vector(1, 2, 3) # Vector([1., 2., 3.])
poly.append_point(vec1)
poly.points # Vector([[1., 2., 3.]])
poly.points[0] # Vector([1., 2., 3.])
您使用 Vector
调用的任何函数都将被 __array_function__
拦截(ufuncs 除外)。虽然这适用于您的特定情况,但您需要修改它以使其更适用于任何类型的输入。
我有一个多边形 class,它使用 2d ndarray 来存储它的点。 class中的每个点都是一个Vectorclass的实例,这个Vectorclass继承了numpy的ndarray。我目前正在使用 numpy.vstack 附加点,但问题是我的向量实例被转换为它们的父实例 class、numpy.ndarray.
import numpy as np
class Vector(np.ndarray):
def __new__(cls, *args, **kwargs):
arr = np.asarray([args[0], args[1], args[2]]).view(cls)
arr = arr.astype('float64')
return arr
class Polygon(object):
def __init__(self):
self.points = np.array([]).reshape(0, 3)
def append_point(self, point):
self.points = np.vstack([self.points, point])
poly = Polygon()
vec1 = Vector(1, 2, 3)
print(type(vec1)) # output: <class '__main__.Vector'>
poly.append_point(vec1)
print(poly.points) # output: [[1. 2. 3.]]
print(type(poly.points[0])) # output: <class 'numpy.ndarray'>
有更好的方法吗?
如果你想保留子类,我认为你需要覆盖 __array_function__
方法:
class Vector(np.ndarray):
def __new__(cls, *args, **kwargs):
arr = np.asarray([args[0], args[1], args[2]]).view(cls)
arr = arr.astype('float64')
return arr
def __array_function__(self, func, types, args, kwargs):
x,y = args[0]
return func([x.view(np.ndarray), y.view(np.ndarray)], **kwargs).view(Vector)
这会给
poly = Polygon()
vec1 = Vector(1, 2, 3) # Vector([1., 2., 3.])
poly.append_point(vec1)
poly.points # Vector([[1., 2., 3.]])
poly.points[0] # Vector([1., 2., 3.])
您使用 Vector
调用的任何函数都将被 __array_function__
拦截(ufuncs 除外)。虽然这适用于您的特定情况,但您需要修改它以使其更适用于任何类型的输入。