【发布时间】:2020-02-18 17:08:28
【问题描述】:
我已将我的问题归结为一个可重现的小测试用例:
在文件 1 (custom_cython.pyx) 文件中,我有以下内容:
import numpy as np
cimport numpy as np
cimport cython
ctypedef np.uint8_t DTYPE_B_t
ctypedef np.uint16_t CELL_ID_t
ctypedef np.int64_t DTYPE_INT64_t
cdef struct LOOKUPMEM_t:
DTYPE_B_t filled_flag
CELL_ID_t key_i
CELL_ID_t key_j
CELL_ID_t key_k
DTYPE_INT64_t offset
DTYPE_INT64_t num_elements
cdef LOOKUPMEM_t[:] lookup_memory
my_dtype = [("filled_flag", np.uint8, 1),
("ijk", np.uint16, 3),
("offset_and_num", np.int64, 2)]
input_numpy_dtype = np.dtype(my_dtype, align=True)
lookup_memory = np.zeros(5000, dtype=input_numpy_dtype)
在文件 2 (custom_cython_test.py) 中,我有以下内容:
from custom_cython import lookup_memory
print(lookup_memory)
当我运行 python custom_cython_test.py 时,我最终得到 ValueError: Expected 0 dimension(s), got 1 在线 lookup_memory = np.zeros(5000, dtype=input_numpy_dtype)
在我的结构定义中,我尝试在 dtype 创建中使用cdef packed struct LOOKUPMEM_t 和align=False,这会产生相同的错误。
我在 Python 3.7.3 上使用 Cython 版本 0.29.12 和 Numpy 1.16.4。
我之前已经成功地将 cython memoryviews 分配给 1-D numpy 数组,所以我很困惑为什么我明显的 1d cdef LOOKUPMEM_t[:] lookup_memory 期望为 0 维。谁能告诉我这是怎么回事?
【问题讨论】:
-
不管怎样,我能够使用 Python 3.6.8 和 Cython 0.29.15 进行复制。还不知道问题出在哪里。
-
谢谢你,至少我知道我没疯!
-
有问题的错误似乎源于 Cython 生成的代码,该代码来自一个名为
__Pyx_ValidateAndInit_memviewslice的相当复杂的函数。我对 Cython 的 Typed Memoryview 区域并不是很熟悉,所以如果不仔细阅读该代码,我仍然不清楚这意味着什么...... -
有趣的是,如果你把它改成
lookup_memory = np.zeros(5000, dtype=input_numpy_dtype).reshape(1,5000),它就会变成ValueError: Buffer has wrong number of dimensions (expected 1, got 2),这与之前的错误格式略有不同,奇怪吗? -
不奇怪;后一个错误是因为实际上将形状设置为 (1, 5000) 使其成为二维数组,因此您需要声明
cdef LOOKUPMEM_t[:, :] lookup_memory以便它是二维的。如果你这样做,第一个错误仍然会发生。
标签: python numpy cython memoryview