python c标准偏差的扩展名

时间:2010-08-03 23:31:42

标签: python c performance standard-deviation

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

这是我到目前为止所做的:

    #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.");
}

6 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

获得item后,您可以使用PyNumber_Float获取其浮动值:

PyObject* floatitem = PyNumber_Float(item);

现在您需要检查并退出错误(if(!floatitem) return 0 - 或goto到您在代码的上一部分中增加任何内容的位置,例如你的案件list)。如果没有错误,PyFloat_AsDouble会为您提供所需的double值,以便在其余的C编码循环中使用:

double ditem = PyFloat_AsDouble(floatitem);

之后你可以减去floatitem并开始你的快乐方式。不要担心PyNumber_Float中的转换开销 - 如果你首先传递一个浮动列表,就不会有任何问题;-)。如果您仍然担心(如果某人确实通过了非浮动需要转换,则宁愿给出错误)如果您坚持,可以使用PyFloat_Check(但我建议至少使用特殊套管int并且long项目,除非您想要真正困惑和不满意的用户;-)。同样,我也强烈建议学习和使用PySequence_Fast和朋友,而不是通过特别要求列表而不是其他类型的序列而惊人的用户! - 。)。

答案 2 :(得分:1)

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

第一种选择是使用NumPy。在您对另一个答案的评论中,您提到将列表转换为数组是很昂贵的。如果标准偏差计算是您对数据执行的唯一位置,那么这可能是真的。

除此之外,我会选择CythonHere是Cython和NumPy的比较。在这种情况下,Cython的表现不如NumPy,但更重要的是,为csum实现的代码可以通过改变来计算标准偏差。

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

另一种设计会保持一个运行总计,并允许你添加点,直到你溢出双倍。

答案 5 :(得分:0)

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