Python numpy.ndarray子类和零秩数组

Python numpy.ndarray子类和零秩数组,python,numpy,subclassing,Python,Numpy,Subclassing,我正在尝试创建numpy.ndarray的子类。它非常简单,只是一个numpy数组,包含一些额外的属性和操作这些属性的方法。在大多数情况下,它工作得很好,但是当使用诸如np.sum之类的约化时,我遇到了一个问题 首先,我读了和 似乎当我创建ndarray的子类时,它在零秩数组->标量转换方面的行为有所不同 在本例中,我只使用可能最简单的派生类,它实际上什么都不做: class XArray(np.ndarray): pass x = np.eye(2) y = x.view(type=X

我正在尝试创建
numpy.ndarray
的子类。它非常简单,只是一个numpy数组,包含一些额外的属性和操作这些属性的方法。在大多数情况下,它工作得很好,但是当使用诸如
np.sum
之类的约化时,我遇到了一个问题

首先,我读了和

似乎当我创建
ndarray
的子类时,它在零秩数组->标量转换方面的行为有所不同

在本例中,我只使用可能最简单的派生类,它实际上什么都不做:

class XArray(np.ndarray):
    pass
x = np.eye(2)
y = x.view(type=XArray)
print type(np.sum(x)), type(np.sum(y))

<type 'numpy.float64'> <type '__main__.XArray'>
除了两个问题外,我对此没有异议:

  • 这是处理这个特殊情况的合适地方吗?我不知道普通numpy数组的转换发生在哪里,所以我不知道它应该发生在我的派生类的哪里

  • 这是否足以使我的子类工作,或者我将继续有兼容性问题。我是否应该放弃子类化
    ndarray


  • 这里的目标是与常规numpy阵列100%兼容。可以,并且预期某些操作将丢失派生类型信息并返回
    ndarray
    基类。我对此很满意,我只是不能编写代码来在
    ndarray
    的休息时间进行操作。

    是的,应该可以。代码本身在ufunc_object.c中,搜索PyArray_Return(就在它前面)。谢谢。这有助于了解这是从哪里来的。确切地说,据我所知,这个逻辑发生在ufunc_object.c中的_find_array_wrap中。它在所有参数上循环,寻找具有最高优先级的参数并选择其array_wrap方法。但是,它会跳过任何传递PyArray_CheckExact()的参数。如果找不到任何符合条件的array_wrap方法(即,所有参数都是精确的ndarray),它将调用PyArray_Return(),该函数将执行标量转换。
    class XArray(np.ndarray):
        def __array_wrap__(self, obj):
            if len(obj.shape)==0:
                return obj[()]
            else:
                return np.ndarray.__array_wrap__(obj)
    a = np.sum(np.eye(2).view(XArray))
    print type(a)
    
    <type 'numpy.float64'>