2010-08-03 95 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

如果你想在大型數據集簡單的統計數據,你可以隨機抽樣的數據的一個子集,並取其平均和標準差。這將會產生近似值的「標準誤差」,並且您採用的樣本越多,樣本越小。如果您不需要統計信息的高精度,則不需要讀取所有數據。