我写的这个 python C 模块只是返回 inf

This python C module I wrote is just returning inf

提问人:FilterFeeder 提问时间:11/1/2023 最后编辑:FilterFeeder 更新时间:11/1/2023 访问量:75

问:

所以我只是想学习 C,这实际上是我用 C 编码的第一天,所以请相应地期待。

我正在尝试制作一个 python 模块,该模块采用一个 numpy 数组,在其上滑动一个窗口,对于每个子窗口,它应该计算标准偏差,并将其存储在返回给 python 的新 numpy 数组中。

出于某种原因,这会在 python 中返回“inf”,或者返回非常大的数字(取决于我更改的随机代码行)。我尝试将计算简化为平均值(所以实际上,这是一个粗糙的低通滤波器),但我仍然得到这些荒谬的值。我有一种感觉,我缺少一些关于我如何获取和返回 python 值的东西。

#include <Python.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <numpy/arrayobject.h>


float calculateStandardDeviation(float *arr, int startIndex, int windowSize) {
    float mean = 0.0;
    float variance = 0.0;

    // Calculate the mean of the subarray
    for (int i = startIndex; i < startIndex + windowSize; i++) {
        mean += arr[i];
    }
    mean /= windowSize;

    // Calculate the variance
    for (int i = startIndex; i < startIndex + windowSize; i++) {
        variance += pow(arr[i] - mean, 2);
    }
    variance /= windowSize;

    // Calculate the standard deviation
    float standardDeviation = sqrt(variance);
    return standardDeviation;
}

static PyArrayObject *method_stdarray(PyObject * self, PyObject *args){
    PyArrayObject *inputArrayObj;
    int windowSize, stepSize;

    if (!PyArg_ParseTuple(args, "Oii", &inputArrayObj, &windowSize, &stepSize)) {
        return NULL;
    }
    //Make sure it's a numpy array
    if (!PyArray_Check(inputArrayObj)) {
        PyErr_SetString(PyExc_TypeError, "Input array must be numpy array.");
        return NULL;
    }
    // Get dims of array
    int ndim = PyArray_NDIM(inputArrayObj);

    // Make sure its a 1D-array
    if (ndim > 1){PyErr_SetString(PyExc_BaseException, "Input numpy array has too many dimensions."); return NULL;}

    if (PyArray_TYPE(inputArrayObj) != NPY_DOUBLE) {
        PyErr_SetString(PyExc_ValueError, "Input array must be of type float64.");
        return NULL;
    }

    //Get the size
    int arraySize = PyArray_Size(inputArrayObj);

    npy_intp size = PyArray_SIZE(inputArrayObj);
    double* inputArray = PyArray_DATA(inputArrayObj);


    if (inputArray == NULL) {
        PyErr_NoMemory();
        return NULL;
    }


    int numWindows = (arraySize - windowSize) / stepSize + 1;
    npy_intp numpyWindows = numWindows;
    //PyObject *resultList = PyList_New(numWindows);

    PyArrayObject* resultArray = (PyArrayObject*)PyArray_EMPTY(1, &numpyWindows, NPY_DOUBLE, 0);

    if (resultArray == NULL) {
        PyErr_SetString(PyExc_MemoryError, "Failed to allocate memory for the result array.");
        return NULL;
    }

    double* resultData = PyArray_DATA(resultArray);
    
    for (int i = 0; i < numWindows; i++) {
        int startIndex = i * stepSize;
        float result = calculateStandardDeviation(inputArray, startIndex, windowSize);
        resultData[i] = result;
    }
    
    Py_INCREF(inputArrayObj);

    return (PyObject*)resultArray;

}


static PyMethodDef meanyMethods[] = {
    {"vararray", method_stdarray, METH_VARARGS, "Takes a list and two integers, returns a new list of variances of subwindows"},
    {NULL, NULL, 0, NULL}
};


static struct PyModuleDef meanymodule = {
    PyModuleDef_HEAD_INIT,
    "meany",
    "My set of functions for analysing mea data",
    -1,
    meanyMethods
};

PyMODINIT_FUNC PyInit_meany(void) {
    import_array();
    return PyModule_Create(&meanymodule);
}

这是我在 python 中如何称呼它

import meany
import random
import numpy as np

fakeList = np.ones(100)
for i in range(0,100):
    fakeList[i] = fakeList[i] + (random.random())
stdList = meany.vararray(fakeList,20,1)

print(stdList)
python c 模块

评论

5赞 John Bollinger 11/1/2023
如果你是 C 语言的新手,那么从混合语言编程和 Numpy 等复杂框架开始似乎极具挑战性。
0赞 9769953 11/1/2023
您尚未包括 ,但您正在调用 和 。你和数学库有联系吗?math.hpowsqrt
2赞 John Bollinger 11/1/2023
另一方面,不应用于小整数指数。尤其不适用于平方。相反,使用普通乘法更快,(通常)更准确,并且不会产生对数学库的依赖。pow()
0赞 John Bollinger 11/1/2023
在将输入数据提取到 .但是你传递(指向)它的指针,它期望(指向)一个数组。可能还有其他问题,但那是一个绝对的杀手。method_stdarray()doublecalculateStandardDeviation()float
1赞 John Bollinger 11/1/2023
还要注意,这是 C 的基本浮点类型。不要在不知道为什么不应该使用的情况下在 C 中使用。doublefloatdouble

答: 暂无答案