gpt4 book ai didi

python - 当子类化 ndarray 时,为什么转置发生在 __array_finalize__ 之后而不是之前?

转载 作者:行者123 更新时间:2023-12-03 17:12:20 25 4
gpt4 key购买 nike

为简单起见,让我们从 numpy 文档中复制诊断 ndarray 子类:

import numpy as np

class MySubClass(np.ndarray):

def __new__(cls, input_array, info=None):
obj = np.asarray(input_array).view(cls)
obj.info = info
return obj

def __array_finalize__(self, obj):
print('In __array_finalize__:')
print(' self is %s' % repr(self))
print(' obj is %s' % repr(obj))
if obj is None: return
self.info = getattr(obj, 'info', None)

现在让我们做一个简单的例子:
>>> x = MySubClass(np.ones((1,5)))
In __array_finalize__:
self is MySubClass([[1., 1., 1., 1., 1.]])
obj is array([[1., 1., 1., 1., 1.]])
>>> y = x.T
In __array_finalize__:
self is MySubClass([[1., 1., 1., 1., 1.]])
obj is MySubClass([[1., 1., 1., 1., 1.]])

正如我们所看到的,显然不是转置的东西被传递给了 __array_finalize__ .除了将“最终确定”一词的含义扩展到全新领域之外,这种行为的目的是什么?

发送实际输出是否更有意义,即通过此 Hook 进行转置以使其最终确定?

使用我的子类可能需要的任何后处理来修饰基本转置的推荐方法是什么?

最佳答案

这是因为创建新对象时,它们依赖于已经可用的(通用)函数 PyArray_NewFromDescrAndBase 来处理内存分配。 PyArray_Transpose 的源代码揭示首先从现有数组创建新对象,具有相似的形状和步幅,然后通过访问先前分配的内存来纠正这些:

/*
* this allocates memory for dimensions and strides (but fills them
* incorrectly), sets up descr, and points data at PyArray_DATA(ap).
*/
Py_INCREF(PyArray_DESCR(ap));
ret = (PyArrayObject *) PyArray_NewFromDescrAndBase(
Py_TYPE(ap), PyArray_DESCR(ap),
n, PyArray_DIMS(ap), NULL, PyArray_DATA(ap),
flags, (PyObject *)ap, (PyObject *)ap);
if (ret == NULL) {
return NULL;
}

/* fix the dimensions and strides of the return-array */
for (i = 0; i < n; i++) {
PyArray_DIMS(ret)[i] = PyArray_DIMS(ap)[permutation[i]];
PyArray_STRIDES(ret)[i] = PyArray_STRIDES(ap)[permutation[i]];
}

这里 PyArray_NewFromDescrAndBase负责 invoking __array_finalize__ 因此该方法接收的版本具有不正确的形状和步幅(即非转置)。可以做不同的事情,但它需要 PyArray_NewFromDescrAndBase 的额外参数。将调用推迟到 __array_finalize__然后可以在调整形状和步幅后手动完成。

关于python - 当子类化 ndarray 时,为什么转置发生在 __array_finalize__ 之后而不是之前?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60714489/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com