具有重载运算符的自定义C结构上的Numpy矩阵运算

时间:2014-08-04 15:46:38

标签: python numpy ctypes cython

我正在开发一个需要处理自定义C结构矩阵的项目,其中一些C函数通过这些结构实现操作。

到目前为止,我们正在进行如下操作:

  • 使用ctypes
  • 围绕C结构构建python包装类
  • 为该对象覆盖__and____xor__,调用相应的底层C函数
  • 构建包含这些类实例的numpy数组

现在我们面临一些性能问题,我觉得这不是处理这个问题的正确方法,因为我们有一个C库在数据类型上实现本地昂贵的操作,然后numpy在矩阵上实现本地昂贵的操作,但是(我猜)在这个配置中,每个操作都将由python包装器类代理。

有没有办法用numpy实现这个,使操作完全原生?我读过有用于包裹ctypes的类型分为numpy的阵列实用程序(see here),但对于操作符重载?

我们不一定要使用ctypes,但我们希望能够仍然使用python(我相信在代码可维护性方面,它比C具有很大的优势......)

有谁知道这是否可能,以及如何?你会建议其他不同的解决方案吗?

非常感谢!

1 个答案:

答案 0 :(得分:0)

详细说明上面的注释(结构数组与数组结构):

import numpy as np
#create an array of structs
array_of_structs = np.zeros((3,3), dtype=[('a', np.float64), ('b',np.int32)])
#we may as well think of it as a struct of arrays
struct_of_arrays = array_of_structs['a'], array_of_structs['b']
#this should print 8
print array_of_structs['b'].ctypes.data - array_of_structs['a'].ctypes.data

请注意,使用数组的结构'方法需要一种相当不同的编码风格。也就是说,我们在很大程度上必须放弃组织代码的OOP方式。当然,您仍然可以选择将与特定对象相关的所有操作放在单个命名空间中,但是这样的数据布局会鼓励更加矢量化或者更加简单的编码风格。我们宁愿将整个集合或对象矩阵作为我们操作的最小原子构造,而不是在函数之间传递单个对象。

当然,也可以以OOP方式访问相同的数据,这是期望的。但就numpy而言,这对你没什么好处。请注意,出于性能原因,通常还优选将对象的每个属性维护为单独的连续数组,因为连续放置所有属性对于仅对对象属性的子集起作用的操作来说是高效缓存的。

相关问题