NumPy的free-function-reshape()与member-function-reshape()的实现?

时间:2019-08-22 18:28:41

标签: python numpy

我想澄清一下NumPy的自由函数reshape()的实现方式,而不是nd-array的成员函数reshape()的实现方式。

例如:

a = np.reshape(np.array([1,2,3]),[3,1])

a = np.array([1,2,3])
a.reshape([3,1])

我确实知道它们是“不同的”,因为一个是类方法,另一个是函数,但是我的问题更多是关于如何编写脚本/实现它们。

成员方法调用自由功能吗?

赞:

import reshape

class array:

     def __init__(self,my_array):
         self.my_array = my_array

     def reshape(self):
          self.my_array = reshape(self.my_array)

还是有其他事情发生?这是如何编码NumPy数组类的类方法吗?它是在方法中导入并使用一个函数,还是在两个函数定义中复制了相同的代码?你知道我在说什么...

2 个答案:

答案 0 :(得分:2)

我们已经知道的:

在此声明中:

a = np.reshape(np.array([1,2,3]),[3,1])

reshape()是此signature的免费函数。这个signature的array()也是一个自由函数和数组构造函数。

但是,在这些语句中:

a = np.array([1,2,3]) 
a.reshape([3,1])

array()仍然是自由函数和构造函数,但是reshape()是nd-array类/对象的成员函数(方法)。与自由函数reshape()the member function, reshape()不同,它允许shape参数的元素作为单独的参数传递。例如,a.reshape(10,11)等同于a.reshape((10,11))。

回答问题:

这些的实际实现有点难理解,因为numpy的核心功能是用C实现的。就像@hpaulj所说的那样,reshape()委托是对已编译代码的神秘调用。

我怀疑重塑代码看起来更像thisthisthis

static PyObject *
array_reshape(PyArrayObject *self, PyObject *args, PyObject *kwds)
{
    static char *keywords[] = {"order", NULL};
    PyArray_Dims newshape;
    PyObject *ret;
    NPY_ORDER order = NPY_CORDER;
    Py_ssize_t n = PyTuple_Size(args);

    if (!NpyArg_ParseKeywords(kwds, "|O&", keywords,
                PyArray_OrderConverter, &order)) {
        return NULL;
    }

    if (n <= 1) {
        if (n != 0 && PyTuple_GET_ITEM(args, 0) == Py_None) {
            return PyArray_View(self, NULL, NULL);
        }
        if (!PyArg_ParseTuple(args, "O&:reshape", PyArray_IntpConverter,
                              &newshape)) {
            return NULL;
        }
    }
    else {
        if (!PyArray_IntpConverter(args, &newshape)) {
            if (!PyErr_Occurred()) {
                PyErr_SetString(PyExc_TypeError,
                                "invalid shape");
            }
            goto fail;
        }
    }
    ret = PyArray_Newshape(self, &newshape, order);
    npy_free_cache_dim_obj(newshape);
    return ret;

 fail:
    npy_free_cache_dim_obj(newshape);
    return NULL;
}

与此相反:

import reshape

class array:

     def __init__(self,my_array):
         self.my_array = my_array

     def reshape(self):
          self.my_array = reshape(self.my_array)

答案 1 :(得分:1)

In [61]: def myreshape(obj, shape): 
    ...:     return np.asarray(obj).reshape(shape) 
    ...:                                                                                                     
In [62]: myreshape(np.arange(12),(3,4))                                                                      
Out[62]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [63]: myreshape(list(range(12)),(3,4))                                                                    
Out[63]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

其中np.asarray是:

np.array(a, dtype, copy=False, order=order)

也就是说,如果可能的话,它会自己返回a,否则将组成一个数组。

另一种编码方式来测试obj是否具有reshape属性:

In [67]: def myreshape(obj, shape): 
    ...:     if not hasattr(obj,'reshape'): 
    ...:         obj = np.array(obj) 
    ...:     return obj.reshape(shape) 

我已经忽略了order。并没有使用类似的子类测试它的行为 np.matrixnp.ma