在阅读了很多有关numpy / cython的文档后,我仍然无法从cython中的指针创建numpy数组。情况如下。我有一个包含回调函数的cython(* .pyx)文件:
cimport numpy
cdef void func_eval(double* values,
int values_len,
void* func_data):
func = (<object> func_data)
# values.: contiguous array of length=values_len
array = ???
# array should be a (modifiable) numpy array containing the
# values as its data. No copying, no freeing the data by numpy.
func.eval(array)
大多数教程和指南都考虑了将数组转换为指针的问题,但我对相反的情况很感兴趣。
我已经看到了一种使用ctypes库(不是我感兴趣的)的基于纯python的解决方案here。 Cython本身对typed memoryviews的讨论很多。这也不是我要寻找的确切内容,因为我希望所有的numpy优点都能在数组上工作。
编辑:(略作修改)的独立MWE(另存为test.cyx
,通过cython test.cyx
进行编译):
cimport numpy
cdef extern from *:
"""
/* This is C code which will be put
* in the .c file output by Cython */
typedef void (*callback)(double* values, int values_length);
void execute(callback cb)
{
double values[] = {0., 1.};
cb(values, 2);
}
"""
ctypedef void (*callback)(double* values, int values_length);
void execute(callback cb);
def my_python_callback(array):
print(array.shape)
print(array)
cdef void my_callback(double* values, int values_length):
# turn values / values_length into numpy array
# and call my_pytohn_callback
pass
cpdef my_execute():
execute(my_callback)
第二次编辑:
关于possible duplicate:尽管问题是相关的,但正如所指出的那样,给出的第一个答案相当脆弱,它依赖于内存数据标志,这可以说是实现细节。而且,自2014年以来,问题和答案都已经过时,并且cython API也得到了扩展。但是幸运的是,我能够自己解决问题。
首先,您可以将原始指针强制转换为在相同基础内存上运行的类型化MemoryView,而无需通过
对其进行所有权cdef double[:] values_view = <double[:values_length]> values
但是,这还不够,因为我说过我想要一个numpy数组。但是可以将MemoryView转换为numpy数组,只要它具有numpy数据类型。因此,可以通过
array = np.asarray(<np.float64_t[:values_length]> values)
可以很容易地检查数组是否在不拥有它的情况下在正确的内存段上运行。