[英]Function in cython changes numpy array type
我正在使用Cython和numpy,但是與更改numpy數組元素的dtype的cython函數有關的問題很奇怪。 奇怪的是,僅在實際指定數組的輸入類型時才更改dtype。
我在Ubuntu 18.04上使用Cython == 0.29.11,numpy == 1.15.4,python 3.6。
# cyth.pyx
cimport numpy as np
def test(x):
print(type(x[0]))
def test_np(np.ndarray[np.uint32_t, ndim=1] x):
print(type(x[0]))
現在對這個文件進行cythonize並使用以下功能:
>>> from cyth import test, test_np
>>> import numpy as np
>>> a = np.array([1, 2], dtype=np.uint32)
>>> test(a)
<class 'numpy.uint32'>
>>> test_np(a)
<class 'int'>
因此test
按預期方式工作,打印輸入數組中第一個元素的類型-uint32。 但是test_np
實際上確保了傳入數組的類型為uint32,現在顯示了常規Python int作為第一個元素的類型。
即使試圖強制元素為正確的類型也不起作用,即使用:
def test_np(np.ndarray[np.uint32_t, ndim=1] x):
cdef np.uint32_t el
el = x[0]
print(type(el))
仍然導致
>>> test_np(a)
<class 'int'>
在理解這一差異方面的任何幫助將不勝感激。
Cython不會更改數組的類型,但是會返回類型稍有不同的元素。
numpy-array中的數據存儲為32位無符號整數的連續字段。 訪問x[0]
意味着創建一個Python對象(因為Python解釋器無法處理原始C-int) np.uint32
對於每個numpy- np.uint32
都有專用的包裝器類,並返回一個np.uint32
。
另一方面,Cython將所有簡單的C整數類型(例如long
, int
等)映射到Python整數(有意義)上。
現在,當導入numpy時, x[0]
不再意味着使用numpy數組的__getitem__()
(它將返回np.uint32
),而是C整數(在這種情況下為unsigned 4byte),它將轉換為Python整數,因為“ return XXX”表示在def函數中表示結果必須是Python對象。
這確實意味着該數組具有不同的類型-Cython將這些類型映射為Python對象時,它們的映射方式不同。
如果要以np.uint32
-objects的形式訪問數據,則可以調用__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__
而不調用基礎ndarray的__getitem__
而是在C級訪問數據。 調用底層對象的__getitem__
進行內存視圖:
def test_np(np.uint32_t[:] x):
print(type(x[0]))
print(type(x.base.__getitem__(0))) # instead of x.__getitem__(0)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.