将非内存连续的 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 数组的主要内容,如果未能解决你的问题,请参考以下文章