将结构化数组传递给Cython失败(我认为这是Cython的错误) [英] Passing structured array to Cython, failed (I think it is a Cython bug)
问题描述
假设我有
a = np.zeros(2, dtype=[('a', np.int), ('b', np.float, 2)])
a[0] = (2,[3,4])
a[1] = (6,[7,8])
然后我定义相同的Cython结构
then I define the same Cython structure
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
我的问题是如何解决?谢谢.
My question is how to fix it? Thank you.
推荐答案
此pyx
可以编译并导入:
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)
我从评论中提到的测试示例开始,然后处理您的案例.我认为关键的更改是将打包结构的第一个元素定义为int a[2]
.因此,如果任何元素是数组,则第一个必须是数组才能正确设置结构.
I started with the test example mentioned in my comment, and played with your case. I think the key change was to define the first element of the packed structure to be int a[2]
. So if any element is an array, the first must an array to properly set up the structure.
显然是测试文件没有捕获的错误.
Clearly an error that the test file isn't catching.
将元素定义为int a[1]
不起作用,可能是因为dtype
删除了这样的尺寸:
Defining the element as int a[1]
doesn't work, possibly because the dtype
removes such a dimension:
In [47]: np.dtype([('a', np.int, 1), ('b', np.float, 2)])
Out[47]: dtype([('a', '<i4'), ('b', '<f8', (2,))])
定义dtype
来解决这个问题并不难,直到问题被提出并得到修补为止.
Defining the dtype
to get around this shouldn't be hard until the issue is raised and patched.
struct
可能具有a[1]
,但是数组dtype
必须使用元组指定大小:('a','i',(1,))
. ('a','i',1)
将使尺寸为()
.
The struct
could have a[1]
, but the array dtype
would have to specify the size with a tuple: ('a','i',(1,))
. ('a','i',1)
would make the size ()
.
如果其中一个struct数组是2d,则看起来所有数组都必须是:
If one of the struct arrays is 2d, it looks like all of them have to be:
cdef packed struct mystruct:
int a[1][1]
float b[2][1]
int c[2][2]
退后一步,我想知道在cython
中处理复杂的结构化数组有什么意义.对于某些操作,将字段作为单独的变量进行传递也不能很好地工作.例如,用myfunc(a['a'],a['b'])
代替myfunc(a)
.
Stepping back a bit, I wonder what's the point to processing a complex structured array in cython
. For some operations wouldn't it work just as well to pass the fields as separate variables. For example myfunc(a['a'],a['b'])
instead of myfunc(a)
.
这篇关于将结构化数组传递给Cython失败(我认为这是Cython的错误)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!