【发布时间】:2018-09-16 07:47:04
【问题描述】:
我正在尝试学习 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,其中i 的值在迭代器每次传递到下一个元素时增加一。当我使用a=np.arange(10) 运行该函数时,打印语句显示如下内容:
(2.121995791e-314, 0.0)
(<numpy.flatiter object at 0x0000024A2CE27B20>)
(4.2439915824e-314, 1.0)
(<numpy.flatiter object at 0x0000024A2CE27B20>)
(6.365987374e-314, 2.0)
(<numpy.flatiter object at 0x0000024A2CE27B20>)
(8.4879831653e-314, 3.0)
(<numpy.flatiter object at 0x0000024A2CE27B20>)
# rest not shown here
这不是我所期望的,因为迭代器似乎仍然指向数组的相同元素,value 返回的值基本上为零,但不是a 的值(数字 0 -9)。但是迭代器似乎确实在函数结束时停止了,因为函数成功终止并且返回的数组具有与a 相同的形状。
所以我的问题是:
value = (<double*>np.PyArray_ITER_DATA(ita))[0]这行实际上是什么意思?<double*>声明指针类型?np.PyArray_ITER_DATA正是 API 所说的。那么[0]呢?我做错了什么以及如何修改代码?如果
a=np.arange(2,8),那么test1(a)应该给array([ 2, 4, 6, 8, 10, 12])。
【问题讨论】:
-
我认为您正在传入具有整数 dtype 的数组,然后尝试将其读取为双精度
-
@DavidW 你是对的。当我将
a明确声明为float64类型时,它会按预期工作。为什么这很重要?我的第一个问题仍然存在。我仍然不确定那条线实际上做了什么,我想知道为什么print(ita)给出相同的地址,即使ita确实在访问数组的不同元素。
标签: python arrays numpy cython