我试图学习cython,我修改了发现的示例here。在
#pyx file
import numpy as np
cimport numpy as np
import cython
np.import_array()
def test1(a):
out = np.empty(a.shape, np.double)
cdef np.flatiter ita = np.PyArray_IterNew(a)
cdef np.flatiter ito = np.PyArray_IterNew(out)
cdef double value
cdef double i
i = 0.0
while np.PyArray_ITER_NOTDONE(ita):
value = (<double*>np.PyArray_ITER_DATA(ita))[0]
print(ita) # for debugging
print(value,i) # for debugging
value = value + i
(<double*>np.PyArray_ITER_DATA(ito))[0] = value
i += 1.0
np.PyArray_ITER_NEXT(ita)
np.PyArray_ITER_NEXT(ito)
return out
因此,我希望函数通过i
来添加输入数组的每个元素,其中{a=np.arange(10)
运行函数时,print语句显示如下内容:
这不是我所期望的,因为迭代器似乎仍然指向数组的同一个元素,value
返回的值本质上是零,但不是{a
相同。在
所以我的问题是:
这行value = (<double*>np.PyArray_ITER_DATA(ita))[0]
实际上是什么意思?<double*>
声明指针类型?np.PyArray_ITER_DATA
正是API所说的。那么[0]
呢?
我出了什么问题?如何修改代码?如果a=np.arange(2,8)
,那么{
问题是
arange
在默认情况下给你一个int
数组,然后你把它解释成double
数组(被误解为双精度的小整数通常在1e-300左右,所以这通常是一个很好的线索)。理想情况下,您应该确保检查函数中的dtype
。在回答您进一步的问题:
print(ita)
正在打印迭代器对象的地址,而不是它当前访问的数据。因此它总是显示相同的地址。在np.PyArray_ITER_DATA(ita)
获取指向当前数据位地址的指针。因为它被设计成任何numpy数组的通用接口,我们不知道它的类型,所以它是void*
。<double*>
你告诉Cython这个指针实际上指向一个double
。[0]
查找存储在该指针上的值相关问题 更多 >
编程相关推荐