2010-08-03 96 views
1

我正在写一个c扩展名来计算他的标准偏差。性能很重要,因为它将在大型数据集上执行。当我从列表中获得项目时,我很难弄清楚如何获得pyobject的价值。这是我第一次为python编写一个c扩展,感谢任何帮助。显然,我不知道如何正确使用代码示例按钮:(标准差的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."); 
} 

回答

4

你可能会重新发明轮子Python目前有几个科学计算库如SciPyNumpy,它们大多是围绕C库包装,即实现诸如标准偏差。

+0

我目前使用numpy的进行计算,但名单必须首先转换为numpy的阵列,我想,以避免由于列表很大,整个数据集是几百兆。我不是专家,但也许不计算性能需要花很多钱,但我想看看在使用Python廓线仪的一个速度上的差异。 – Xavier 2010-08-03 23:41:56

+0

转换为numpy的阵列可能不会像你想象的那样大的交易。如果你从加载文件或数据库数据,你已经做了相当大的开销加载,作为一个普通的Python列表。如果您将数据直接加载到Numpy数组中,那么您将消除该开销。即使你有从正常列表“转换”到一个数组,你以后可以保存您numpy的阵列快速加载。 http://docs.scipy.org/doc/numpy/reference/generated/numpy.load.html – Cerin 2010-08-04 12:45:28

0

此方法将通过列表中的项目的数目的限制。

另一个设计将保持运行总计,并让您添加点直到您溢出双。

1

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

PyObject* floatitem = PyNumber_Float(item); 

现在,你需要检查和退出的错误(if(!floatitem) return 0 - 或goto到一个位置,你decref任何你可能已在您的代码的前一部分中增加,例如在您的案例中为list)。如果没有错误,PyFloat_AsDouble让您在C-编码循环的其余部分使用的必需double值:

double ditem = PyFloat_AsDouble(floatitem); 

之后就可以decref floatitem去你的快乐的方式。不要担心PyNumber_Float中的转换开销过多 - 如果您首先通过了浮动列表,则不会有任何变化;-)。如果你仍然担心(如果有人通过非浮动需要转换,宁可给出错误),如果你坚持(但我会建议至少要特别套管intlong项目,除非你想真正困惑和不开心的用户;-)。以类似的方式,我也强烈建议学习和使用PySequence_Fast和朋友,而不是惊人的用户通过特别要求列表而不是其他类型的序列! - )。

1

只要提到几乎肯定比写C扩展更好。

第一个选项是使用NumPy。在你对另一个答案的评论中,你提到将列表转换为数组是昂贵的。如果标准偏差计算是您对数据进行处理的唯一一点,那么这可能是真实的。

除此之外,我会去CythonHere是Cython和NumPy的比较。在这种情况下,Cython的性能不如NumPy,但更重要的是,对于csum实施的代码可以稍微改变以计算标准偏差。

1

您是否考虑使用cython来编写您的扩展。这是完美的这种类型的东西

0

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