1

我正在编写 ac 扩展来计算他的标准偏差。性能很重要,因为它将在大型数据集上执行。从列表中获取项目后,我很难弄清楚如何获取 pyobject 的值。这是我第一次为 python 编写 ac 扩展,感谢任何帮助。显然我不知道如何正确使用代码示例按钮:(

这是我到目前为止所拥有的:

    #include <Python.h>
static PyObject*
func(PyObject *self, PyObject *args)
{
  PyObject *list, *item;
  Py_ssize_t i, len;
  if (!PyArg_UnpackTuple(args, "func", 1, 1, &list)){
    return NULL;
  }
  printf("hello world\n");
  Py_INCREF(list);
  len = PyList_GET_SIZE(list);
  for (i=0;i<len;i++){
    item = PyList_GET_ITEM(list, i);
    PyObject_Print(item,stdout,0);
  }
  return list;
}

static char func_doc[] = "This function calculates standard deviation.";

static PyMethodDef std_methods[] = {
  {"func", func, METH_VARARGS, func_doc},
  {NULL, NULL}
};

PyMODINIT_FUNC
initstd(void)
{
  Py_InitModule3("std", std_methods, "This is a sample docstring.");
}
4

6 回答 6

4

你可能正在重新发明轮子。Python 有几个科学计算库,例如SciPyNumpy,它们主要是 C 库的包装器,它们实现了标准偏差等功能。

于 2010-08-03T23:36:40.970 回答
1

一旦你有了,你可以用PyNumber_Floatitem得到它的浮点值:

PyObject* floatitem = PyNumber_Float(item);

现在您需要检查并退出错误(if(!floatitem) return 0- 或goto到您在代码的前一部分中删除您可能已经增加的任何内容的位置,例如在您的情况下list)。如果没有错误,PyFloat_AsDouble会为您提供在 C 编码循环的其余部分中使用所需的double值:

double ditem = PyFloat_AsDouble(floatitem);

之后,您可以拒绝floatitem并走自己的快乐之路。不要过分担心转换开销PyNumber_Float——如果你首先传递了一个浮点列表,就不会有任何开销;-)。如果您仍然担心(如果有人确实通过了需要转换的非浮点数,宁愿给出错误),PyFloat_Check如果您坚持可以使用(但我建议至少使用特殊情况intlong项目,除非您想要真正困惑和不满意的用户; -)。同样,我也强烈建议学习和使用PySequence_Fast和朋友们,而不是通过明确要求列表而不是其他类型的序列来让用户感到惊讶!-)。

于 2010-08-04T00:02:22.983 回答
1

顺便提一下,几乎可以肯定有比编写 C 扩展更好的方法。

第一种选择是使用 NumPy。在您对另一个答案的评论中,您提到将列表转换为数组很昂贵。如果标准偏差计算是您对极不可能的数据所做的唯一一点,这可能是正确的。

除此之外,我会选择Cython是 Cython 和 NumPy 的比较。在这种情况下,Cython 的性能不如 NumPy,但更重要的是,csum可以轻松更改实现的代码以计算标准偏差。

于 2010-08-04T00:06:55.953 回答
1

您是否考虑过使用cython编写扩展程序。它非常适合这种类型的东西

于 2010-08-04T00:07:43.887 回答
0

此方法将受到列表中项目数量的限制。

另一种设计将保持一个运行总分,让你加分,直到你溢出双倍。

于 2010-08-03T23:37:30.750 回答
0

如果您想要对大型数据集进行简单统计,您可以随机抽取数据的子集并取其平均值和标准差。这将有一个近似的“标准误差”,并且你采集的样本越多,它就会越小。如果您不需要高精度的统计数据,则不需要读取所有数据。

于 2010-08-04T00:25:59.590 回答