Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么Cython期望0维?_Python_Numpy_Cython_Memoryview - Fatal编程技术网

Python 为什么Cython期望0维?

Python 为什么Cython期望0维?,python,numpy,cython,memoryview,Python,Numpy,Cython,Memoryview,我已将我的问题归结为一个小的可复制测试用例: 在文件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 f

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

在文件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)
from custom_cython import lookup_memory

print(lookup_memory)
在文件2中(custom_cython_test.py),我有以下内容:

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)
from custom_cython import lookup_memory

print(lookup_memory)
当我运行
python custom\u cython\u test.py
时,我得到了
ValueError:Expected 0维,在
lookup\u memory=np.zero(5000,dtype=input\u numpy\u dtype)行上得到了1

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

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


我以前已经成功地将cython MemoryView分配给了1-D numpy数组,所以我很困惑,为什么我的1d
cdef LOOKUPMEM\u t[:]lookup\u memory
需要0维。有谁能告诉我发生了什么事吗?

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

    CELL_ID_t key_i
    CELL_ID_t key_j
    CELL_ID_t key_k
结合数据类型的这一部分:

("ijk", np.uint16, 3)
对于组合的
offset\u和_num
字段也是如此

问题是,当memoryview接口看到一个类似元组的字段,如
(“ijk”,np.uint16,3)
,它希望将其解压到一个由3个元素组成的一维数组中,但结构中的下一个键只是
CELL\u ID\u t key\u 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初始化。

我可以使用Python 3.6.8和Cython 0.29.15进行复制。我还不知道问题出在哪里。谢谢你,至少我知道我没有疯!所讨论的错误似乎起源于Cython从一个相当复杂的函数生成的代码,该函数名为
\uuuPyx\uValidateAndInit\uMemViewSlice
。我对Cython的类型化Memoryview区域并不十分熟悉,因此如果不仔细阅读代码,我仍然不清楚这意味着什么……有趣的是,如果将其更改为
lookup\u memory=np.zeros(5000,dtype=input\u numpy\u dtype)。重塑(15000)
它将变成
ValueError:Buffer的维度数错误(预期为1,得到2)
这是一个与前一个错误稍有不同的格式,奇怪?不奇怪;后一个错误是因为事实上将形状设置为(15000)会使其成为二维数组,因此需要声明
cdef LOOKUPMEM\u t[:,:]lookup\u memory
,使其为二维。如果这样做,第一个错误仍然会发生。