Могу ли я создать PyObject * (numpy.float32) - PullRequest
2 голосов
/ 26 января 2012

Я пытаюсь реализовать функцию в C (расширение Python) для возврата типа данных numpy.float32.Можно ли реально создать объект и вернуть его так, чтобы в python объект, возвращаемый при вызове функции, был экземпляром numpy.float32?

(расширение C)

PyObject *numpyFloatFromFloat(float d)
{
   ret = SomeAPICall(d)
   return ret;
}

(в python)

a = something_special()

type(a)
-> numpy.float32

Сейчас все попытки использования API, описанного в справочной документации, иллюстрируют, как создать массив, который выдает numpy.ndarray, и до сих пор использование типов данных приводит к C-Тип float, который преобразуется в double в Python.И по какой-то причине, о которой я не знаю, мне действительно нужен IEEE 754 float32 в конце этой функции.

Решение на данный момент:

something.pyx:

cdef extern from "float_gen.h"
    float special_action(void)

def numpy_float_interface():
    return numpy.float32(special_action())

float_gen.h

static inline float special_action() { return 1.0; }

Я не вижу здесь никакой потери данных, но я не уверен.Я знаю, что numpy.float32 обрабатывается как float C или float32_t, поэтому, когда я вызываю special_action в файле pyx, он не преобразует его в double (как это делает python), он должен быть без потерь.

Edit Окончательное решение было совсем другим, мне просто нужно было понять, как правильно расширить Python в C с помощью библиотеки numpy.

Ниже просто возвращается np.float32 (32)

static PyObject *get_float(PyObject *self, PyObject *args) {
    float v = 32;
    PyObject *np_float32_val = NULL;
    PyArray_Descr *descr = NULL;
    if(! PyArg_ParseTuple(args, ""))
        return NULL;
    if(! (descr = PyArray_DescrFromType(NPY_FLOAT32))) {
        PyErr_SetString(PyExc_TypeError, "Improper descriptor");
        return NULL;
    }

    np_float32_val = PyArray_Scalar(&v, descr, NULL);
    printf("%lu\n", np_float32_val->ob_refcnt);
    return np_float32_val;
}

1 Ответ

1 голос
/ 26 января 2012

Этот простой модуль возвращает np.int32 из числа с плавающей запятой. Поплавок cdef на самом деле не нужен, так как np.float32 () должен приводить все, что вы ему даете, к np.float32.

test_mod.pyx

import numpy as np
def fucn():
    cdef float a
    a = 1
    return np.float32(a)

tester.py

import pyximport
pyximport.install()
import test_mod

a = test_mod.func()
print type(a) # <type 'numpy.float32'>
...