Numpy 将结构化数组传递给Cython失败(我认为这是Cython错误)

Numpy 将结构化数组传递给Cython失败(我认为这是Cython错误),numpy,cython,Numpy,Cython,如果我有 a = np.zeros(2, dtype=[('a', np.int), ('b', np.float, 2)]) a[0] = (2,[3,4]) a[1] = (6,[7,8]) 然后我定义了相同的Cython结构 import numpy as np cimport numpy as np cdef packed struct mystruct: np.int_t a np.float_t b[2] def test_mystruct(mystruct[:] x

如果我有

a = np.zeros(2, dtype=[('a', np.int),  ('b', np.float, 2)])
a[0] = (2,[3,4])
a[1] = (6,[7,8])
然后我定义了相同的Cython结构

import numpy as np
cimport numpy as np

cdef packed struct mystruct:
  np.int_t a
  np.float_t b[2]

def test_mystruct(mystruct[:] x):
  cdef:
    int k
    mystruct y

  for k in range(2):
    y = x[k]
    print y.a
    print y.b[0]
    print y.b[1]
在这之后,我跑步

test_mystruct(a)
我得到了一个错误:

ValueError                                Traceback (most recent call last)
<ipython-input-231-df126299aef1> in <module>()
----> 1 test_mystruct(a)
_cython_magic_5119cecbaf7ff37e311b745d2b39dc32.pyx in _cython_magic_5119cecbaf7ff37e311b745d2b39dc32.test_mystruct (/auto/users/pwang/.cache/ipython/cython/_cython_magic_5119cecbaf7ff37e311b745d2b39dc32.c:1364)()
ValueError: Expected 1 dimension(s), got 1
ValueError回溯(最近一次调用)
在()
---->1测试结构(a)
_cython_magic_5119; cecbaf7ff37e311b745d2b39dc32.pyx in_cython_magic_5119cecbaf7ff37e311b745d2b39dc32.test_mystruct(/auto/users/pwang/.cache/ipython/cython/_cython_magic_5119cecbaf7ff37e311b745d2b39dc32.c:1364)()
ValueError:应为1个维度,得到1个

我的问题是如何修复它?谢谢。

pyx
编译并导入ok:

import numpy as np
cimport numpy as np

cdef packed struct mystruct:
  int a[2]    # change from plain int
  float b[2]
  int c

def test_mystruct(mystruct[:] x):
  cdef:
    int k
    mystruct y

  for k in range(2):
    y = x[k]
    print y.a
    print y.b[0]
    print y.b[1]

dt='2i,2f,i'
b=np.zeros((3,),dtype=dt)
test_mystruct(b)
我从我的评论中提到的测试示例开始,并处理了您的案例。我认为关键的变化是将压缩结构的第一个元素定义为
inta[2]
。因此,如果任何元素是数组,那么第一个元素必须是数组才能正确设置结构

很明显,这是一个测试文件无法捕获的错误

将元素定义为
inta[1]
不起作用,可能是因为
dtype
删除了这样一个维度:

In [47]: np.dtype([('a', np.int, 1),  ('b', np.float, 2)])
Out[47]: dtype([('a', '<i4'), ('b', '<f8', (2,))])



退一步说,我想知道在
cython
中处理复杂的结构化数组有什么意义。对于某些操作来说,将字段作为单独的变量传递也同样有效。例如,
myfunc(a['a'],a['b'])
代替
myfunc(a)

有一种获取c结构的数据类型的通用方法,但它涉及一个临时变量:

cdef mystruct _tmp
dt = np.asarray(<mystruct[:1]>(&_tmp)).dtype
cdef mystruct\u tmp
dt=np.asarray((&u tmp)).dtype

这至少需要numpy 1.5。请参阅此处的讨论:

这是一个什么样的重复?对不起,我编辑了这个问题,请您删除CristiánAntuña的重复标志。谢谢。@hpaulj:一开始这是一个不同的问题。彭宇:删除评论。成功地将结构化数组传递给C压缩结构。这就找到了解决相同错误的方法:@hpaulj,问题是如果C结构中有数组定义,它会导致错误。在两篇文章中,我看不出如何避免这个错误。
cdef mystruct _tmp
dt = np.asarray(<mystruct[:1]>(&_tmp)).dtype