为什么Cython期望0维?

2024-05-16 20:44:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我已将我的问题归结为一个小的可复制测试用例:

在文件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时,我在lookup_memory = np.zeros(5000, dtype=input_numpy_dtype)行上以ValueError: Expected 0 dimension(s), got 1结束

在我的结构定义中,我尝试在数据类型创建中使用cdef packed struct LOOKUPMEM_talign=False,这会产生相同的错误

我使用的是Python 3.7.3,Cython版本为0.29.12,Numpy版本为1.16.4

我以前已经成功地将cython MemoryView分配给了1-D numpy数组,所以我很困惑为什么我的表观1dcdef LOOKUPMEM_t[:] lookup_memory需要0维。谁能告诉我发生了什么事


Tags: 文件numpyidcustomnpcelllookupcython
1条回答
网友
1楼 · 发布于 2024-05-16 20:44:49

问题似乎是结构的这一部分:

    CELL_ID_t key_i
    CELL_ID_t key_j
    CELL_ID_t key_k

结合数据类型的这一部分:

("ijk", np.uint16, 3)

对于组合的offset_and_num字段也是如此

问题是,当memoryview接口看到一个类似元组的字段(如("ijk", np.uint16, 3))时,它希望将其解压为一个包含3个元素的1-D数组,但结构中的下一个键只是CELL_ID_t key_i,一个0-D标量

如果我将结构更改为与Numpy数据类型更紧密地匹配,它将起作用:

cdef struct LOOKUPMEM_t:
    DTYPE_B_t filled_flag
    CELL_ID_t ijk[3]
    DTYPE_INT64_t offset_num_elements[2]

因此,对于如何继续,您有一些选择。如果确实希望保持结构的相同方式,可以这样做,并以不同的方式格式化数据类型。由于很容易查看具有不同数据类型的Numpy数组,因此,如果要在其他用例中保留现有的数据类型格式,也可以在memoryview初始化中使用不同的数据类型

相关问题 更多 >