我在电影里见过几次这样的东西
Pandas source
:
def nancorr(ndarray[float64_t, ndim=2] mat, bint cov=0, minp=None):
# ...
N, K = (<object> mat).shape
这意味着
ndarray
打电话
mat
是
type-casted
到Python对象。
*
经进一步检查,这似乎是因为如果不是编译错误,就会出现编译错误。我的问题是:
为什么首先需要这种类型的转换
?
这里有几个例子。
This
答案很简单,元组打包在Cython中不像在Python中那样工作,但它似乎不是元组解包问题。(不管怎样,这是一个很好的答案,我不想挑刺。)
取下面的脚本,
shape.pyx
. 它将在编译时失败,并显示“无法将'npy_intp*'转换为Python对象”
from cython cimport Py_ssize_t
import numpy as np
from numpy cimport ndarray, float64_t
cimport numpy as cnp
cnp.import_array()
def test_castobj(ndarray[float64_t, ndim=2] arr):
cdef:
Py_ssize_t b1, b2
# Tuple unpacking - this will fail at compile
b1, b2 = arr.shape
return b1, b2
但同样,问题似乎不是元组
拆包
,就其本身而言。同样的错误也会导致失败。
def test_castobj(ndarray[float64_t, ndim=2] arr):
cdef:
# Py_ssize_t b1, b2
ndarray[float64_t, ndim=2] zeros
zeros = np.zeros(arr.shape, dtype=np.float64)
return zeros
看起来,这里没有元组解包。元组是第一个参数
np.zeros
.
def test_castobj(ndarray[float64_t, ndim=2] arr):
"""This works"""
cdef:
Py_ssize_t b1, b2
ndarray[float64_t, ndim=2] zeros
b1, b2 = (<object> arr).shape
zeros = np.zeros((<object> arr).shape, dtype=np.float64)
return b1, b2, zeros
这同样有效(也许是最令人困惑的):
def test_castobj(object[float64_t, ndim=2] arr):
cdef:
tuple shape = arr.shape
ndarray[float64_t, ndim=2] zeros
zeros = np.zeros(shape, dtype=np.float64)
return zeros
例子:
>>> from shape import test_castobj
>>> arr = np.arange(6, dtype=np.float64).reshape(2, 3)
>>> test_castobj(arr)
(2, 3, array([[0., 0., 0.],
[0., 0., 0.]]))
*也许这和
arr
成为一个记忆视图?但那是在黑暗中拍摄的。
另一个例子是Cython
docs
:
cpdef int sum3d(int[:, :, :] arr) nogil:
cdef size_t i, j, k
cdef int total = 0
I = arr.shape[0]
J = arr.shape[1]
K = arr.shape[2]
在这种情况下,简单地标引
arr.shape[i]
防止我觉得奇怪的错误。
这也适用于:
def test_castobj(object[float64_t, ndim=2] arr):
cdef ndarray[float64_t, ndim=2] zeros
zeros = np.zeros(arr.shape, dtype=np.float64)
return zeros