【问题标题】:Numpy matrix operations on custom C structures with overloaded operators具有重载运算符的自定义 C 结构上的 Numpy 矩阵运算
【发布时间】:2014-09-27 03:47:22
【问题描述】:

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

到目前为止,我们的工作如下:

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

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

有没有办法用 numpy 实现这一点,使操作完全原生?我读过有用于将 ctypes 类型包装到 numpy 数组中的实用程序(seehere),但是运算符重载呢?

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

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

非常感谢!

【问题讨论】:

  • 是的,我建议另一种解决方案。 numpy 并没有真正设计为在这种使用下高效。这真的取决于你想做什么,所以也许你可以详细说明一下;但总的来说,“数组结构”方法比“结构数组”方法更友好。请注意,您可以通过适当地偏移您的结构/跨步您的数组来互换使用这两种方法。

标签: python numpy ctypes cython


【解决方案1】:

详细说明上述评论(结构数组与数组结构):

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 方式。自然地,您仍然可以选择将与特定对象相关的所有操作放在单个命名空间中,但这样的数据布局鼓励更多的矢量化或 numpythonic 编码风格。与其在函数之间传递单个对象,不如将整个对象集合或矩阵作为我们操作的最小原子结构。

当然,同样的数据也可以在需要的地方以 OOP 方式访问。但就 numpy 而言,这对你没有多大好处。请注意,出于性能原因,通常最好将对象的每个属性维护为单独的连续数组,因为将所有属性连续放置对于仅作用于对象属性子集的操作来说缓存效率低。

【讨论】:

  • 感谢您的回答,我不知道这种索引 numpy 数组的方式。但是,恐怕这种方法不适用于我的情况,因为 C structs 包含非标准数据类型(来自 GMP 库的大整数),并且它们之间的操作是作为 C 函数实现的(并且我他们是黑盒子)。
  • 我仍然缺乏真正理解你的问题的背景,但我觉得你最好坚持使用 C 来解决这个子问题。没有一个 numpy/scipy 函数可以很好地处理您的大整数数学。尽管如此,如果您在 C 中封装了一些功能子集,则可以在 python 中构建其余功能。例如,您可以在 python 中将结构的 C++ 向量的特定属性视为数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多