将结构化数组传递给Cython失败(我认为这是Cython的错误) [英] Passing structured array to Cython, failed (I think it is a Cython bug)

查看:70
本文介绍了将结构化数组传递给Cython失败(我认为这是Cython的错误)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有

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]

https://github.com/cython//blob/c4c2e3d8bd760386b26dbd6cffbd4e30ba0a7d13/tests/memoryview/numpy_memoryview.pyx

退后一步,我想知道在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆