【问题标题】:python c extension for standard deviation标准差的python c扩展
【发布时间】:2010-08-03 23:31:41
【问题描述】:

我正在编写一个 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.");
}

【问题讨论】:

    标签: python c performance standard-deviation


    【解决方案1】:

    您可能正在重新发明轮子。 Python 有几个科学计算库,如SciPyNumpy,它们大多是C 库的封装,实现标准差等功能。

    【讨论】:

    • 我目前正在使用 numpy 进行计算,但必须先将列表转换为 numpy 数组,我想避免这种情况,因为列表很大并且整个数据集有数百个兆字节。虽然我不是专家,也许这不会在计算性能方面花费太多,但我想看看使用其中一个 python 分析器的速度差异。
    • 转换为 Numpy 数组可能没有你想象的那么重要。如果您从文件或数据库中加载数据,则将其加载为普通的 Python 列表已经付出了相当大的开销。如果您首先将数据直接加载到 Numpy 数组中,您将消除该开销。即使您必须从普通列表“转换”为数组,您也可以保存 Numpy 数组以供以后快速加载。 docs.scipy.org/doc/numpy/reference/generated/numpy.load.html
    【解决方案2】:

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

    PyObject* floatitem = PyNumber_Float(item);
    

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

    double ditem = PyFloat_AsDouble(floatitem);
    

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

              猜你喜欢
              • 2016-11-20
              • 2015-11-06
              • 1970-01-01
              • 2021-07-16
              • 1970-01-01
              • 2010-11-07
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多