6
爲了學習新東西,我正在嘗試在C中重新實現numpy.mean()函數。它應該採用3D數組並返回一個二維數組,其平均值爲沿着軸0的元素。我設法計算所有值的平均值,但並不真正知道如何將新數組返回給Python。從我讀到的消息來源來看,我認爲這涉及到一些嚴重的雜耍,我不太熟悉(但願意這樣做)。從C擴展返回numpy數組
我迄今爲止代碼:
#include <Python.h>
#include <numpy/arrayobject.h>
// Actual magic here:
static PyObject*
myexts_std(PyObject *self, PyObject *args)
{
PyArrayObject *input=NULL;
int i, j, k, x, y, z, dims[2];
double out = 0.0;
if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &input))
return NULL;
x = input->dimensions[0];
y = input->dimensions[1];
z = input->dimensions[2];
for(k=0;k<z;k++){
for(j=0;j<y;j++){
for(i=0;i < x; i++){
out += *(double*)(input->data + i*input->strides[0]
+j*input->strides[1] + k*input->strides[2]);
}
}
}
out /= x*y*z;
return Py_BuildValue("f", out);
}
// Methods table - this defines the interface to python by mapping names to
// c-functions
static PyMethodDef myextsMethods[] = {
{"std", myexts_std, METH_VARARGS,
"Calculate the standard deviation pixelwise."},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC initmyexts(void)
{
(void) Py_InitModule("myexts", myextsMethods);
import_array();
}
我明白爲止(和請糾正我,如果我錯了)是,我需要創建一個新的PyArrayObject,這將是我的輸出(可能與PyArray_FromDims?)。然後我需要一個地址陣列來存儲這個數組,並用數據填充它。我將如何去做這件事?
編輯:
做的指針(這裏:http://pw1.netcom.com/~tjensen/ptr/pointers.htm)更多閱讀後,我實現了我的宗旨。現在又出現了另一個問題:我在哪裏可以找到numpy.mean()的原始實現?我想看看它是如何,python操作比我的版本快得多。我假設它避免了醜陋的循環。
這裏是我的解決方案:
static PyObject*
myexts_std(PyObject *self, PyObject *args)
{
PyArrayObject *input=NULL, *output=NULL; // will be pointer to actual numpy array ?
int i, j, k, x, y, z, dims[2]; // array dimensions ?
double *out = NULL;
if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &input))
return NULL;
x = input->dimensions[0];
y = dims[0] = input->dimensions[1];
z = dims[1] = input->dimensions[2];
output = PyArray_FromDims(2, dims, PyArray_DOUBLE);
for(k=0;k<z;k++){
for(j=0;j<y;j++){
out = output->data + j*output->strides[0] + k*output->strides[1];
*out = 0;
for(i=0;i < x; i++){
*out += *(double*)(input->data + i*input->strides[0] +j*input->strides[1] + k*input->strides[2]);
}
*out /= x;
}
}
return PyArray_Return(output);
}
這裏是numpy的的平均值的源代碼:https://github.com/numpy/numpy/blob/3abd8699dc3c71e389356ca6d80a2cb9efa16151/numpy/core/src/multiarray/calculation.c#L744 – SingleNegationElimination