2017-09-02 109 views
0

TLDR:如何在纯循环中定义is_float_object函数?在Cython中使用Numpy的PyArray_IsScalar

我想了解pandas._libs中的一些函数,这些函数在pandas/_libs/src/numpy_helper.h中定义并通过pandas/_libs/src/util.pxd公开。 AFAICT我的困惑与.h文件中的命名空间没有直觉有关。

is_float_object为例。这在numpy_helper.h

#include "Python.h" 
#include "numpy/arrayobject.h" 
#include "numpy/arrayscalars.h" 
[...] 

PANDAS_INLINE int is_float_object(PyObject* obj) { 
    return (PyFloat_Check(obj) || PyArray_IsScalar(obj, Floating)); 
} 

我想不通的地方Floating的定义,它是如何钻进命名空间中定义的,什么类型的cdef extern from ...我需要用得到它变成一个用Cython文件。

PyArray_IsScalarnumpy/ndarrayobject.h定义:

#define PyArray_IsScalar(obj, cls)          \ 
    (PyObject_TypeCheck(obj, &Py##cls##ArrType_Type)) 

中有大熊猫/ _libs/src目录/ numpy.pxd这让我想起了 “##” 是指一些特殊的魔力评论在作怪:

# Cannot be supported due to ## ## in macro: 
# bint PyArray_IsScalar(object, verbatim work) 

Floating哪里定义?在不需要中间文件numpy_helper.h的情况下,直接在cython中定义这个函数需要什么?

回答

2

##是C预处理器级联。 Floating不在任何名称空间中,但仅由C预处理器在字符串连接中使用。本节PyArray_IsScalar(obj, Floating)是由C预处理器翻译为:

(PyObject_TypeCheck(obj, &PyFloatingArrType_Type)) 

如果要定义在用Cython的is_float_object你应该这样做级联自己:

from cpython cimport PyFloat_Check, PyObject_TypeCheck, PyTypeObject 

cdef extern from "numpy/arrayobject.h": 
    PyTypeObject PyFloatingArrType_Type 

cdef int is_float_object(obj): 
    return (PyFloat_Check(obj) or (PyObject_TypeCheck(obj, &PyFloatingArrType_Type))); 

(该cdef extern from "numpy/arrayobject.h"是有点一个猜测,但我认为它来自那里)

+0

谢谢你看看这个。我有更多的尝试尝试,但到目前为止,这导致了段错误。好像它不检查PyFloatingArrType_Type是否存在,直到实际尝试调用该函数。这看起来与我期望编译语言所做的相反。我解释错了吗? – user2957943

+0

它看起来像ndarrayobject.h#包含__multiarray_api.h,它标记PyFloatingArrType_Type与NPY_NO_EXPORT。我猜这意味着我运气不好。 https://github.com/explosion/thinc/blob/master/include/numpy/__multiarray_api.h#L112 – user2957943

+0

我怀疑你需要首先运行'numpy.import_array()'。 'PyFloatingArrType_Type'很可能是一个全局变量,它只能由模块导入代码初始化。它在编译时存在,但在初始化之前没有有效的值。 – DavidW