如何在保留继承的同时使用 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 除外)。虽然这适用于您的特定情况,但您需要修改它以使其更适用于任何类型的输入。