расширение Python c для стандартного отклонения - PullRequest
1 голос
/ 04 августа 2010

Я пишу расширение c, чтобы вычислить стандартное отклонение. Производительность важна, потому что она будет выполняться для больших наборов данных. Мне трудно понять, как получить значение pyobject, как только я получу элемент из списка. Я впервые пишу расширение c для python, и любая помощь приветствуется. Видимо, я не знаю, как правильно использовать кнопку примера кода: (

Это то, что я имею до сих пор:

    #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 ]

4 голосов
/ 04 августа 2010

Возможно, вы изобретаете велосипед.Для Python существует несколько научных вычислительных библиотек, таких как SciPy и Numpy , которые в основном являются оболочками для библиотек C и реализуют такие функции, как стандартное отклонение.

1 голос
/ 04 августа 2010

Рассматривали ли вы использовать cython для написания своего расширения. Идеально подходит для такого типа вещей

1 голос
/ 04 августа 2010

Просто упомяну, что почти наверняка есть лучший способ, чем написать расширение C.

Первый вариант - использовать NumPy. В комментарии к другому ответу вы упоминаете, что преобразовать список в массив дорого. Это может быть правдой, если вычисление стандартного отклонения - единственный бит, который вы делаете с данными, что крайне маловероятно.

За исключением этого, я бы пошел на Cython . Здесь - сравнение Cython и NumPy. В этом случае Cython уступает NumPy, но, что более важно, код, реализованный для csum, можно легко изменить для вычисления стандартного отклонения.

1 голос
/ 04 августа 2010

Если у вас есть item, вы можете получить его значение с плавающей запятой с помощью PyNumber_Float :

PyObject* floatitem = PyNumber_Float(item);

Теперь вам нужно проверить и выйти при ошибке (if(!floatitem) return 0 - илиgoto к месту, где вы расшифровываете все, что вы могли увеличить в предыдущей части кода, например, в вашем случае list).Если нет ошибки, PyFloat_AsDouble дает вам необходимое double значение для использования в остальной части вашего C-кодированного цикла:

double ditem = PyFloat_AsDouble(floatitem);

, после чего вы можете decf floatitem и перейтитвой веселый путь.Не беспокойтесь слишком много о затратах на конвертацию в PyNumber_Float - их не будет, если вы сначала получили список с плавающей точкой ;-).Если вы все еще волнуетесь (скорее, выдадите ошибку, если кто-то пропустит не-float, требующий преобразования), вы можете использовать PyFloat_Check, если вы настаиваете (но я бы предложил по крайней мере специальные элементы int и longесли вы не хотите действительно недоумевающих и недовольных пользователей ;-).В том же духе я бы настоятельно рекомендовал изучить и использовать PySequence_Fast и друзей, а не удивлять пользователей, требуя специальных списков, а не других типов последовательностей! -).

0 голосов
/ 04 августа 2010

Если вы хотите получить простую статистику по большим наборам данных, вы можете случайным образом выбрать часть данных и взять их среднее и стандартное отклонение. Это будет иметь «стандартную ошибку» аппроксимации, и чем больше выборок вы берете, тем меньше будет. Если вам не нужна высокая точность статистики, вам не нужно читать все данные.

0 голосов
/ 04 августа 2010

Этот метод будет ограничен количеством элементов в списке.

Другой дизайн будет держать промежуточный итог и позволит вам добавлять очки, пока вы не переполнили двойную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...