Я пытаюсь изучить Cython, и я изменил пример, найденный здесь .
#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)
, оператор print показывает что-то вроде:
(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])
.