我可以创建一个 PyObject* (numpy.float32)

发布于 2024-12-28 22:04:17 字数 1569 浏览 2 评论 0原文

我正在尝试用 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 中的双精度。由于某种我不知道的原因,我确实需要在此函数末尾有一个实际的 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;
}

I am trying to implement a function in C (Extending Python) to return a numpy.float32 data type. Is it possible to actually create an object and return it, such that in python the object returned from calling the function is an instance of numpy.float32 ?

(C Extension)

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

(in python)

a = something_special()

type(a)
-> numpy.float32

Right now all attempts at using the API documented in the reference documentation illustrate how to make an Array which yields a numpy.ndarray, and so far using the data types yields a C-type float which converts to a double in python. And for some reason that I'm unaware of, I really need an actual IEEE 754 float32 at the end of this function.

Solution thus far:

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; }

I don't see any loss in data here but I can't be certain. I know a numpy.float32 is treated as a C float or float32_t so assuming when I call special_action in the pyx file that it doesn't convert it to a double (as python does) it should be lossless.

Edit
The ultimate solution was very different, I just had to understand how to properly extend Python in C with the numpy library.

Below just returns a 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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小瓶盖 2025-01-04 22:04:17

这个简单的模块从 C 浮点数返回 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)

测试器.py

import pyximport
pyximport.install()
import test_mod

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

This simple module returns np.int32 from a C float. The cdef float isn't really necessary as np.float32() should coerce whatever you give to it to a 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'>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文