Python 在cython中使用numpy.array
我想用cython格式重写一个类,并将其保存为demo.pyx。类的输入参数可以是带有Python 在cython中使用numpy.array,python,arrays,pointers,numpy,cython,Python,Arrays,Pointers,Numpy,Cython,我想用cython格式重写一个类,并将其保存为demo.pyx。类的输入参数可以是带有Nx2形状的2D np.array,例如a=np.array([[0.2,-0.8],[3.7,0.02],…,[-0.92,-3.33]]),或者是实例a=[0.1,2.7]的列表 cimport numpy as np DTYPE = np.float64 ctypedef np.float64_t DTYPE_t cdef class halo_positions(object): cdef un
Nx2
形状的2D np.array,例如a=np.array([[0.2,-0.8],[3.7,0.02],…,[-0.92,-3.33]])
,或者是实例a=[0.1,2.7]
的列表
cimport numpy as np
DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
cdef class halo_positions(object):
cdef unsigned double *x
cdef unsigned double *y
def __init__(self, np.ndarray[np.float64_t,ndim=2,mode='c'] positions):
self.x = &positions[:,0]
self.y = &positions[:,1]
我尝试编写的内容会导致以下错误消息:
running build_ext
cythoning demo.pyx to demo.c
Error compiling Cython file:
------------------------------------------------------------
...
cimport numpy as np
DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
cdef class halo_positions(object):
cdef unsigned double *x
^
------------------------------------------------------------
demo.pyx:5:9: Unrecognised type modifier combination
Error compiling Cython file:
------------------------------------------------------------
...
cimport numpy as np
DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
cdef class halo_positions(object):
cdef unsigned double *x
cdef unsigned double *y
^
------------------------------------------------------------
demo.pyx:6:9: Unrecognised type modifier combination
Error compiling Cython file:
------------------------------------------------------------
...
ctypedef np.float64_t DTYPE_t
cdef class halo_positions(object):
cdef unsigned double *x
cdef unsigned double *y
def __init__(self, np.ndarray[np.float64_t,ndim=2,mode='c'] positions):
self.x = &positions[:,0]
^
------------------------------------------------------------
demo.pyx:8:17: Cannot take address of Python variable
Error compiling Cython file:
------------------------------------------------------------
...
cdef class halo_positions(object):
cdef unsigned double *x
cdef unsigned double *y
def __init__(self, np.ndarray[np.float64_t,ndim=2,mode='c'] positions):
self.x = &positions[:,0]
self.y = &positions[:,1]
^
------------------------------------------------------------
demo.pyx:9:17: Cannot take address of Python variable
我知道我使用指针的方式有问题,但是如果我想保持
x
和y
的类型不明确,我需要使用这个。我怎样才能使我的课程
有效 操作符获取对象的地址。您希望将self.x
指定为位置[0]
的地址。因此它应该是self.x=&position[0]
。这表示将自调用x的成员设置为positions的第0个元素的地址。您试图做的是将x的地址设置为某物。但你是不允许这样做的<代码>&只允许出现在等式的右侧。操作符获取对象的地址。您希望将self.x
指定为位置[0]
的地址。因此它应该是self.x=&position[0]
。这表示将自调用x的成员设置为positions的第0个元素的地址。您试图做的是将x的地址设置为某物。但你是不允许这样做的<代码>&只允许出现在等式的右侧。操作符获取对象的地址。您希望将self.x
指定为位置[0]
的地址。因此它应该是self.x=&position[0]
。这表示将自调用x的成员设置为positions的第0个元素的地址。您试图做的是将x的地址设置为某物。但你是不允许这样做的<代码>&只允许出现在等式的右侧。操作符获取对象的地址。您希望将self.x
指定为位置[0]
的地址。因此它应该是self.x=&position[0]
。这表示将自调用x的成员设置为positions的第0个元素的地址。您试图做的是将x的地址设置为某物。但你是不允许这样做的&
仅允许在方程式的右侧。Cython无法将numpy数组转换为双*
,您可以使用双[:]
,例如:
cimport numpy as np
cdef class halo_positions(object):
cdef double *x
cdef double *y
def __init__(self, double[:] positions):
self.x = &positions[0]
self.y = &positions[1]
def debug(self):
print self.x[0], self.y[0]
但这是非常危险的:
a = np.array([1.0, 2.0, 3.0, 4.0])
hp = halo_positions(a)
hp.debug()
del a
hp.debug() # x and y is wild pointer now.
也许您应该在
halo_positions
类中保留对位置的引用。Cython无法将numpy数组转换为double*
,您可以使用double[:]
,例如:
cimport numpy as np
cdef class halo_positions(object):
cdef double *x
cdef double *y
def __init__(self, double[:] positions):
self.x = &positions[0]
self.y = &positions[1]
def debug(self):
print self.x[0], self.y[0]
但这是非常危险的:
a = np.array([1.0, 2.0, 3.0, 4.0])
hp = halo_positions(a)
hp.debug()
del a
hp.debug() # x and y is wild pointer now.
也许您应该在halo_positions
类中保留对位置的引用。Cython无法将numpy数组转换为double*
,您可以使用double[:]
,例如:
cimport numpy as np
cdef class halo_positions(object):
cdef double *x
cdef double *y
def __init__(self, double[:] positions):
self.x = &positions[0]
self.y = &positions[1]
def debug(self):
print self.x[0], self.y[0]
但这是非常危险的:
a = np.array([1.0, 2.0, 3.0, 4.0])
hp = halo_positions(a)
hp.debug()
del a
hp.debug() # x and y is wild pointer now.
也许您应该在halo_positions
类中保留对位置的引用。Cython无法将numpy数组转换为double*
,您可以使用double[:]
,例如:
cimport numpy as np
cdef class halo_positions(object):
cdef double *x
cdef double *y
def __init__(self, double[:] positions):
self.x = &positions[0]
self.y = &positions[1]
def debug(self):
print self.x[0], self.y[0]
但这是非常危险的:
a = np.array([1.0, 2.0, 3.0, 4.0])
hp = halo_positions(a)
hp.debug()
del a
hp.debug() # x and y is wild pointer now.
也许您应该在halo_positions
类中保留对positions
的引用。您的代码有几个问题。首先,也是最容易修复的是,没有“无符号双精度”这样的东西,因此首先应该删除无符号的
另外,&positions[:,0]
不是获取数组地址的正确语法,因为:
将返回Python对象。您需要执行&定位[0,0]
,它指向数组的初始元素
应该指出的是,您的\uuuu init\uuuu
只适用于Numpy数组,而不适用于列表,正如您所说的那样。您必须事先将任何列表转换为数组。还要记住,您需要通过指针保持对任何数组的活动引用,否则您将遇到麻烦
不过,根据代码的用途,在类中使用指针变量通常不是最安全的选择 您的代码有几个问题。首先,也是最容易修复的是,没有“无符号双精度”这样的东西,因此首先应该删除无符号的
另外,&positions[:,0]
不是获取数组地址的正确语法,因为:
将返回Python对象。您需要执行&定位[0,0]
,它指向数组的初始元素
应该指出的是,您的\uuuu init\uuuu
只适用于Numpy数组,而不适用于列表,正如您所说的那样。您必须事先将任何列表转换为数组。还要记住,您需要通过指针保持对任何数组的活动引用,否则您将遇到麻烦
不过,根据代码的用途,在类中使用指针变量通常不是最安全的选择 您的代码有几个问题。首先,也是最容易修复的是,没有“无符号双精度”这样的东西,因此首先应该删除无符号的
另外,&positions[:,0]
不是获取数组地址的正确语法,因为:
将返回Python对象。您需要执行&定位[0,0]
,它指向数组的初始元素
需要指出的是,您的\uuuuu init\uuuu
仅适用于Numpy数组,一种