Cython не меняет тип массива, но возвращает элемент немного другого типа.
Данные в массиве numpy хранятся как непрерывное поле 32-битных целых чисел без знака. Доступ к x[0]
означает создание объекта Python (поскольку интерпретатор Python не может обрабатывать необработанные C-ints) - numpy имеет выделенный класс-обертку для каждого типа numpy-d и возвращает np.uint32
-объект.
С другой стороны, Cython отображает все целочисленные типы C (например, long
, int
и т. Д.) Просто на целое число Python (что имеет смысл).
Теперь, когда numpy импортируется, x[0]
больше не означает использование __getitem__()
массива numpy (который будет возвращать np.uint32
-объект), а целое число C (в данном случае 4-байтовое число без знака), которое преобразуется в Python-целое число, потому что «return XXX» означает в функции def, что результатом должен быть объект Python.
Что означает, что массив имеет другой тип - типы отображаются по-разному при преобразовании в Python-объект с помощью Cython.
Если вы хотите получить доступ к данным как np.uint32
-объектам, вы можете вызвать __getitem__
вместо [..]
([..]
переводится Cython как доступ к необработанным C-данным):
%%cython
cimport numpy as np
def test_np(np.ndarray[np.uint32_t, ndim=1] x):
print(type(x[0])) # int
print(type(x.__getitem__(0))) # numpy.uint32
Когда вы используете типизированные представления памяти, а не ndarray, то прямой вызов __getitem__
вернет целое число Python __getitem__
представления памяти не вызывает __getitem__
базового ndarray, но обращается к данным на C -уровень. Чтобы вызвать __getitem__
базового объекта для просмотра в памяти:
def test_np(np.uint32_t[:] x):
print(type(x[0]))
print(type(x.base.__getitem__(0))) # instead of x.__getitem__(0)