将非内存连续的 c/c++ 数据包装为 numpy 数组

Posted

技术标签:

【中文标题】将非内存连续的 c/c++ 数据包装为 numpy 数组【英文标题】:Wrapping non-memory-contiguous c/c++ data as numpy array 【发布时间】:2014-03-20 21:11:10 【问题描述】:

我有一个 C++ 类,它为许多“粒子”(上下文是物理模拟)提供数据接口。每个粒子的数据都存储在一个结构中,并且该类有一个指向结构的指针数组。我真的不想弄乱这个存储方案,因为:

数据以非我自己设计的二进制格式存储在磁盘上,编写一个新函数将文件读入其他存储结构并不简单。 我有大量其他 C/C++ 代码围绕相同的数据存储方案设计,如果存储结构发生更改,这些代码将无法使用或需要进行大修。

现在,我想用 python 做一些可视化。理想的场景是以 numpy 数组的形式访问我的数据,这样我就可以使用各种 numpy 函数(直方图、排序、分箱、统计等)。我有一个使用 SWIG 将我的类包装到 Python 中的工作解决方案。缺点是我需要制作数据的部分副本(从埋在 C++ 类中的结构到 numpy 数组)。随着我对这些模拟工作的进展,我正在推动我的硬件施加的限制,这意味着我想将粒子的数量推高到数据占用大部分可用内存的地方。所以要不惜一切代价避免复制。

有没有办法将一个 numpy 数组映射到这些乱七八糟的数据上?一些闲逛似乎指向一个“否”的答案,但是如果我稍微放宽我的“无复制”要求并允许一些回旋余地来创建一个额外的指针数组呢?我会勾勒出我的想法:

struct particle_data

  double x[3];
  double vx[3];
  //more data


class Snap

  struct particle_data *P; //this gets allocated, so data is accessed as P[i].x[j] and so on
  //a bunch of other functions, flags, etc.

我在想的是我可以创建一个指针数组,例如

double **x0;
//of course allocate some memory for the array here...
for(int i=0; i<max; i++)

  x0 = &P[i].x[0]

希望能以某种方式让它在 python 中作为一个 numpy 的双精度数组很好地发挥作用。如果我特别幸运,可以避免创建类似的数组 x1 和 x2,因为 x0[i]+1 = x1[i] 和 x0[i]+2 = x2[i]。

不过,我不知道这是否可行或如何设置。在一个完美的世界里,我可以坚持使用 SWIG,但我有一种预感,如果可能的话,这将涉及到自己编写一些包装器。

【问题讨论】:

找到了这个相关的问题,但还是卡住了。 ***.com/questions/4355524/… 作为注释,结构particle_data 可以由现有的c/c++ 代码分配,然后通过cython 暴露给python 环境作为numpy 大小的双精度数组6,无需复制。也就是说,我不知道您是否可以在不复制数据的情况下更进一步,因为结构不连续。 @flebool 嗯,有用的提示,但在这里不会起作用,因为particle_data 中的“//更多数据”包含各种整数、浮点数、双精度数... 【参考方案1】:

我将通过确定如何将 C++ 对象存储为数组来解决此问题。如果您能找到一种方法,那么通过 SWIG 将其暴露给 Python 将很容易。如果你甚至不能在 C++ 级别做到这一点(可能没有办法做你想做的事),那么你就不能走得更远。但是,您似乎认为应该有一个数组结构可以用来表示您的数据,因此请先在 C++ 中朝这个方向推进。一旦解决,大部分从战斗中获得的机会都将获胜。

【讨论】:

以上是关于将非内存连续的 c/c++ 数据包装为 numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章

如何将包装为字符串的向量转换为熊猫数据框中的numpy数组?

将非异步方法(进行网络调用)包装到异步中

20200111(Numpy)

Numpy基础学习

numpy 笔记 view,copy和numpy的运行速度

Numpy基础:数组和矢量计算