Arrays 在Cython代码中将C数组强制转换为numpy数组/Cython类型的memoryview

Arrays 在Cython代码中将C数组强制转换为numpy数组/Cython类型的memoryview,arrays,numpy,cython,Arrays,Numpy,Cython,我需要使用一个C库,它给我一个函数,该函数以回调函数作为输入。这个回调函数依次接受一个数组并返回一个值。比如说 double candidate(double[] x); 将是一个有效的回调 我想用Cython实现回调函数,用Numpy简化实现 所以我尝试实现一个函数 cdef double cythonCandidate(double[] x): 现在我想立即将x“强制转换”为numpy数组,然后使用numpy执行操作 例如,我可能想写以下内容: cdef double euclidean

我需要使用一个C库,它给我一个函数,该函数以回调函数作为输入。这个回调函数依次接受一个数组并返回一个值。比如说

double candidate(double[] x);
将是一个有效的回调

我想用Cython实现回调函数,用Numpy简化实现

所以我尝试实现一个函数

cdef double cythonCandidate(double[] x):
现在我想立即将x“强制转换”为numpy数组,然后使用numpy执行操作

例如,我可能想写以下内容:

cdef double euclideanNorm(double[] x):
    # cast x into a numpy array nx here - dont know how!!
    return np.sum(x * x)
问题1。我该怎么做?如何将C数组强制转换为numpy数组而不进行显式复制,而只引用底层缓冲区


问题2:像我打算的那样使用numpy会有python开销吗?

对于问题1:

%%cython -f
import numpy as np

def test_cast():
    cdef double *x = [1, 2, 3, 4, 5]
    cdef double[:1] x_view = <double[:5]>x  # cast to memoryview, refer to the underlying buffer without copy
    xarr = np.asarray(x_view)                # numpy array refer to the underlying buffer without copy
    x_view[0] = 100
    xarr[1] = 200
    x[2] = 300
    print(xarr.flags)                       # OWNDATA flag should be False
    return x[0],x[1],x[2],x[3],x[4]         # (100.0, 200.0, 300.0, 4.0, 5.0)
我不知道这是功能还是bug

第二季度: 当阵列很小时,numpy开销应该很大。请参阅下面的基准测试

%%cython -a
from cython cimport view
import numpy as np

cdef inline double euclideanNorm(double *x, size_t x_size):
    xarr = np.asarray(<double[:x_size]>x)
    return np.sum(xarr*xarr)

cdef inline double euclideanNorm_c(double *x, size_t x_size):
    cdef double ss = 0.0
    cdef size_t i 
    for i in range(x_size):
        ss += x[i] * x[i]
    return ss

def c_norm(double[::1] x):
    return euclideanNorm_c(&x[0], x.shape[0])

def np_norm(double[::1] x):
    return euclideanNorm(&x[0], x.shape[0])
我的电脑中的大阵列:

import numpy as np
small_arr = np.random.rand(100)
print(c_norm(small_arr))
print(np_norm(small_arr))
%timeit c_norm(small_arr)   # 1000000 loops, best of 3: 864 ns per loop
%timeit np_norm(small_arr)  # 100000 loops, best of 3: 8.51 µs per loop
big_arr = np.random.rand(1000000)
print(c_norm(big_arr))
print(np_norm(big_arr))
%timeit c_norm(big_arr)   # 1000 loops, best of 3: 1.46 ms per loop
%timeit np_norm(big_arr)  # 100 loops, best of 3: 4.93 ms per loop

第一季度:

%%cython -f
import numpy as np

def test_cast():
    cdef double *x = [1, 2, 3, 4, 5]
    cdef double[:1] x_view = <double[:5]>x  # cast to memoryview, refer to the underlying buffer without copy
    xarr = np.asarray(x_view)                # numpy array refer to the underlying buffer without copy
    x_view[0] = 100
    xarr[1] = 200
    x[2] = 300
    print(xarr.flags)                       # OWNDATA flag should be False
    return x[0],x[1],x[2],x[3],x[4]         # (100.0, 200.0, 300.0, 4.0, 5.0)
我不知道这是功能还是bug

第二季度: 当阵列很小时,numpy开销应该很大。请参阅下面的基准测试

%%cython -a
from cython cimport view
import numpy as np

cdef inline double euclideanNorm(double *x, size_t x_size):
    xarr = np.asarray(<double[:x_size]>x)
    return np.sum(xarr*xarr)

cdef inline double euclideanNorm_c(double *x, size_t x_size):
    cdef double ss = 0.0
    cdef size_t i 
    for i in range(x_size):
        ss += x[i] * x[i]
    return ss

def c_norm(double[::1] x):
    return euclideanNorm_c(&x[0], x.shape[0])

def np_norm(double[::1] x):
    return euclideanNorm(&x[0], x.shape[0])
我的电脑中的大阵列:

import numpy as np
small_arr = np.random.rand(100)
print(c_norm(small_arr))
print(np_norm(small_arr))
%timeit c_norm(small_arr)   # 1000000 loops, best of 3: 864 ns per loop
%timeit np_norm(small_arr)  # 100000 loops, best of 3: 8.51 µs per loop
big_arr = np.random.rand(1000000)
print(c_norm(big_arr))
print(np_norm(big_arr))
%timeit c_norm(big_arr)   # 1000 loops, best of 3: 1.46 ms per loop
%timeit np_norm(big_arr)  # 100 loops, best of 3: 4.93 ms per loop