问题描述
我想在C ++中使用bool类型的numpy数组,通过Cython传递它的指针。我已经知道如何做它与其他数据类型像uint8。做同样的方式用布尔它不工作。我能够编译,但在运行时有以下异常:
I'd like to use a numpy array of type bool in C++ by passing its pointer via Cython. I already know how to do it with other datatypes like uint8. Doing it the same way with boolean it does not work. I am able to compile but there is the following Exception during runtime:
Traceback (most recent call last):
File "test.py", line 15, in <module>
c = r.count(b, 4)
File "rect.pyx", line 41, in rect.PyRectangle.count (rect.cpp:1865)
def count(self, np.ndarray[bool, ndim=1, mode="c"] array not None, int size):
ValueError: Does not understand character buffer dtype format string ('?')
这里是我的c ++方法:
Here is my c++ method:
void Rectangle::count(bool * array, int size)
{
for (int i = 0; i < size; i++){
std::cout << array[i] << std::endl;
}
}
Cython文件:
# distutils: language = c++
# distutils: sources = Rectangle.cpp
import numpy as np
cimport numpy as np
from libcpp cimport bool
cdef extern from "Rectangle.h" namespace "shapes":
cdef cppclass Rectangle:
Rectangle(int, int, int, int) except +
int x0, y0, x1, y1
void count(bool*, int)
cdef class PyRectangle:
cdef Rectangle *thisptr # hold a C++ instance which we're wrapping
def __cinit__(self, int x0, int y0, int x1, int y1):
self.thisptr = new Rectangle(x0, y0, x1, y1)
def __dealloc__(self):
del self.thisptr
def count(self, np.ndarray[bool, ndim=1, mode="c"] array not None, int size):
self.thisptr.count(&array[0], size)
这里的python脚本调用方法并产生错误:
And here the python script that calls the method and produces the error:
import numpy as np
import rect
b = np.array([True, False, False, True])
c = r.count(b, 4)
如果您需要更多信息,请与我们联系。谢谢!
Please let me know if you need more information. Thank you!
推荐答案
看起来问题是数组类型声明。
根据 boolean arays不支持,但您可以通过将它们转换为无符号8位整数数组来使用它们。
下面是一个简单的例子,它使用一个布尔值的1D数组的和(与 sum()
方法的布尔值NumPy数组相同) p>
It looks like the problem is with the array type declaration.According to the documentation at https://cython.readthedocs.org/en/latest/src/tutorial/numpy.html boolean arays aren't yet supported, but you can use them by casting them as arrays of unsigned eight bit integers.Here's a simple example that takes the sum of a 1D array of boolean values (the same as the sum()
method would for a boolean NumPy array)
from numpy cimport ndarray as ar
cimport numpy as np
cimport cython
@cython.boundscheck(False)
@cython.wraparound(False)
def cysum(ar[np.uint8_t,cast=True] A):
cdef int i, n=A.size, tot=0
for i in xrange(n):
tot += A[i]
return tot
在你的C ++代码中,根据你所做的,你可能需要将指针转换回bool,我不确定。
In your C++ code, depending on what you are doing, you may need to cast the pointer back to a bool, I'm not sure on that.
编辑:这里是一个如何在Cython中转换指针的示例,它应该做你想要的。
我仍然必须以无符号的8位整数的形式输入数组,但是我将指针转换回bool。
here's an example of how to cast the pointer in Cython, which should do what you want.I still had to type the array as an unsigned 8 bit integer, but I then cast the pointer back into a bool.
from numpy cimport ndarray as ar
cimport numpy as np
from libcpp cimport bool
cimport cython
def cysum(ar[np.uint8_t,cast=True] A):
cdef int i, n=A.size, tot=0
cdef bool *bptr
bptr = <bool*> &A[0]
for i in xrange(n):
tot += bptr[i]
return tot
如果你想以一个指针传递数组,你可以在你的Cython文件中使用下面的函数:
If you want to pass the array in as a pointer, you could just use the following function in your Cython file:
cdef bool* arptr(np.uint8_t* uintptr):
cdef bool *bptr
bptr = <bool*> uintptr
return bptr
可以调用
arptr(&A[0])
这篇关于将numpy指针(dtype = np.bool)传递给C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!