我正在尝试在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类型的浮点数,它在python中转换为double。由于某种原因,我不知道,我真的需要一个实际的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被视为C float或float32_t所以假设当我在pyx文件中调用special_action时它没有将它转换为double(就像python那样)它应该是无损的。
修改 最终的解决方案非常不同,我只需要了解如何使用numpy库在C中正确扩展Python。
下面只返回一个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;
}
答案 0 :(得分:1)
这个简单的模块从C float返回np.int32。 cdef float并不是必需的,因为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'>